From: Vasily Tarasov <tarasov@vasily.name>
To: dm-devel@redhat.com
Cc: Joe Thornber <thornber@redhat.com>,
Mike Snitzer <snitzer@redhat.com>,
Christoph Hellwig <hch@infradead.org>,
Philip Shilane <philip.shilane@emc.com>,
Sonam Mandal <sonam.dp42@gmail.com>,
Erez Zadok <ezk@fsl.cs.sunysb.edu>
Subject: [PATCH RFCv2 03/10] dm-dedup: hash computation
Date: Thu, 28 Aug 2014 18:04:55 -0400 [thread overview]
Message-ID: <53ffb650.0878320a.243a.133d@mx.google.com> (raw)
Hash-computation functions. We preallocate a table of hash descriptors
in advance to improve performance.
Signed-off-by: Vasily Tarasov <tarasov@vasily.name>
---
drivers/md/dm-dedup-hash.c | 145 ++++++++++++++++++++++++++++++++++++++++++++
drivers/md/dm-dedup-hash.h | 30 +++++++++
2 files changed, 175 insertions(+), 0 deletions(-)
create mode 100644 drivers/md/dm-dedup-hash.c
create mode 100644 drivers/md/dm-dedup-hash.h
diff --git a/drivers/md/dm-dedup-hash.c b/drivers/md/dm-dedup-hash.c
new file mode 100644
index 0000000..b350004
--- /dev/null
+++ b/drivers/md/dm-dedup-hash.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012-2014 Vasily Tarasov
+ * Copyright (C) 2012-2014 Geoff Kuenning
+ * Copyright (C) 2012-2014 Sonam Mandal
+ * Copyright (C) 2012-2014 Karthikeyani Palanisami
+ * Copyright (C) 2012-2014 Philip Shilane
+ * Copyright (C) 2012-2014 Sagar Trehan
+ * Copyright (C) 2012-2014 Erez Zadok
+ *
+ * This file is released under the GPL.
+ */
+
+#include "dm-dedup-target.h"
+#include "dm-dedup-hash.h"
+#include <linux/atomic.h>
+#include <linux/blk_types.h>
+
+/*
+ * We are declaring and initalizaing global hash_desc, because
+ * we need to do hash computation in endio function, and this
+ * function is called in softirq context. Hence we are not
+ * allowed to perform any operation on that path which can sleep.
+ * And tfm allocation in hash_desc, at one point, tries to take
+ * semaphore and hence tries to sleep. And because of this we get
+ * BUG, which complains "Scheduling while atomic". Hence to avoid
+ * this scenario, we moved the declaration and initialization out
+ * of critical path.
+ */
+static struct hash_desc *slot_to_desc(struct hash_desc_table *desc_table,
+ unsigned long slot)
+{
+ BUG_ON(slot >= DEDUP_HASH_DESC_COUNT);
+ return &(desc_table->desc[slot]);
+}
+
+struct hash_desc_table *desc_table_init(char *hash_alg)
+{
+ int i = 0;
+ struct hash_desc *desc;
+ struct hash_desc_table *desc_table;
+
+ desc_table = kmalloc(sizeof(struct hash_desc_table), GFP_NOIO);
+ if (!desc_table)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < DEDUP_HASH_DESC_COUNT; i++) {
+ desc_table->free_bitmap[i] = true;
+ desc = desc_table->desc + i;
+ desc->flags = 0;
+ desc->tfm = crypto_alloc_hash(hash_alg, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(desc->tfm))
+ return (struct hash_desc_table *)desc->tfm;
+ }
+
+ atomic_long_set(&(desc_table->slot_counter), 0);
+
+ return desc_table;
+}
+
+void desc_table_deinit(struct hash_desc_table *desc_table)
+{
+ int i = 0;
+ struct hash_desc *desc;
+
+ for (i = 0; i < DEDUP_HASH_DESC_COUNT; i++) {
+ desc = desc_table->desc + i;
+ crypto_free_hash(desc->tfm);
+ }
+
+ kfree(desc_table);
+ desc_table = NULL;
+}
+
+static int get_next_slot(struct hash_desc_table *desc_table)
+{
+ unsigned long num = 0;
+ int count = 0;
+
+ do {
+ if (count == DEDUP_HASH_DESC_COUNT)
+ BUG();
+
+ count++;
+ num = atomic_long_inc_return(&(desc_table->slot_counter));
+ num = num % DEDUP_HASH_DESC_COUNT;
+
+ } while (!desc_table->free_bitmap[num]);
+
+ /* XXX: Possibility of race condition here. As checking of bitmap
+ * and its setting is not happening in same step. But it will
+ * work for now, as we declare atleast twice more hash_desc
+ * then number of threads.
+ */
+ desc_table->free_bitmap[num] = false;
+
+ return num;
+}
+
+static void put_slot(struct hash_desc_table *desc_table, unsigned long slot)
+{
+ BUG_ON(slot >= DEDUP_HASH_DESC_COUNT);
+ BUG_ON(desc_table->free_bitmap[slot]);
+ desc_table->free_bitmap[slot] = true;
+}
+
+unsigned int get_hash_digestsize(struct hash_desc_table *desc_table)
+{
+ unsigned long slot;
+ struct hash_desc *desc;
+
+ slot = get_next_slot(desc_table);
+ desc = slot_to_desc(desc_table, slot);
+
+ return crypto_hash_digestsize(desc->tfm);
+}
+
+int compute_hash_bio(struct hash_desc_table *desc_table,
+ struct bio *bio, char *hash)
+{
+ struct scatterlist sg;
+ int ret = 0;
+ unsigned long slot;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+ struct hash_desc *desc;
+
+ slot = get_next_slot(desc_table);
+ desc = slot_to_desc(desc_table, slot);
+
+ ret = crypto_hash_init(desc);
+ if (ret)
+ goto out;
+
+ sg_init_table(&sg, 1);
+ __bio_for_each_segment(bvec, bio, iter, bio->bi_iter) {
+ sg_set_page(&sg, bvec.bv_page, bvec.bv_len,
+ bvec.bv_offset);
+ crypto_hash_update(desc, &sg, sg.length);
+ }
+
+ crypto_hash_final(desc, hash);
+out:
+ put_slot(desc_table, slot);
+ return ret;
+}
diff --git a/drivers/md/dm-dedup-hash.h b/drivers/md/dm-dedup-hash.h
new file mode 100644
index 0000000..9eb791d
--- /dev/null
+++ b/drivers/md/dm-dedup-hash.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012-2014 Vasily Tarasov
+ * Copyright (C) 2012-2014 Geoff Kuenning
+ * Copyright (C) 2012-2014 Sonam Mandal
+ * Copyright (C) 2012-2014 Karthikeyani Palanisami
+ * Copyright (C) 2012-2014 Philip Shilane
+ * Copyright (C) 2012-2014 Sagar Trehan
+ * Copyright (C) 2012-2014 Erez Zadok
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_DEDUP_HASH_H
+#define DM_DEDUP_HASH_H
+
+#define DEDUP_HASH_DESC_COUNT 128
+
+struct hash_desc_table {
+ struct hash_desc desc[DEDUP_HASH_DESC_COUNT];
+ bool free_bitmap[DEDUP_HASH_DESC_COUNT];
+ atomic_long_t slot_counter;
+} /*desc_table*/;
+
+extern void desc_table_deinit(struct hash_desc_table *desc_table);
+extern struct hash_desc_table *desc_table_init(char *crypt_alg);
+extern int compute_hash_bio(struct hash_desc_table *desc_table,
+ struct bio *bio, char *hash);
+extern unsigned int get_hash_digestsize(struct hash_desc_table *desc_table);
+
+#endif /* DM_DEDUP_HASH_H */
--
1.7.1
next reply other threads:[~2014-08-28 22:04 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-28 22:04 Vasily Tarasov [this message]
2015-02-06 21:42 ` [PATCH RFCv2 03/10] dm-dedup: hash computation Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53ffb650.0878320a.243a.133d@mx.google.com \
--to=tarasov@vasily.name \
--cc=dm-devel@redhat.com \
--cc=ezk@fsl.cs.sunysb.edu \
--cc=hch@infradead.org \
--cc=philip.shilane@emc.com \
--cc=snitzer@redhat.com \
--cc=sonam.dp42@gmail.com \
--cc=thornber@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.