[PATCH] Avoid io queue in dm-crypt

From: Richard Kralovic
Date: Wed Oct 20 2010 - 11:11:25 EST


Process io requests from the calling process, not from the io queue. Should
improve cfq scheduler behaviour with dm-crypt.

Signed-off-by: Richard Kralovic <riso@xxxxxx>
---
drivers/md/dm-crypt.c | 42 +++++++++++++-----------------------------
1 files changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 368e8e9..7e2d3a5 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -22,6 +22,7 @@
#include <linux/scatterlist.h>
#include <asm/page.h>
#include <asm/unaligned.h>
+#include <linux/semaphore.h>

#include <linux/device-mapper.h>

@@ -57,6 +58,7 @@ struct dm_crypt_io {
int error;
sector_t sector;
struct dm_crypt_io *base_io;
+ struct semaphore notify;
};

struct dm_crypt_request {
@@ -104,7 +106,6 @@ struct crypt_config {
mempool_t *page_pool;
struct bio_set *bs;

- struct workqueue_struct *io_queue;
struct workqueue_struct *crypt_queue;

char *cipher;
@@ -728,26 +729,16 @@ static void kcryptd_io_write(struct dm_crypt_io *io)
generic_make_request(clone);
}

-static void kcryptd_io(struct work_struct *work)
+static void kcryptd_io(struct dm_crypt_io *io)
{
- struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
-
if (bio_data_dir(io->base_bio) == READ)
kcryptd_io_read(io);
else
kcryptd_io_write(io);
}

-static void kcryptd_queue_io(struct dm_crypt_io *io)
-{
- struct crypt_config *cc = io->target->private;
-
- INIT_WORK(&io->work, kcryptd_io);
- queue_work(cc->io_queue, &io->work);
-}
-
static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
- int error, int async)
+ int error)
{
struct bio *clone = io->ctx.bio_out;
struct crypt_config *cc = io->target->private;
@@ -765,10 +756,7 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,

clone->bi_sector = cc->start + io->sector;

- if (async)
- kcryptd_queue_io(io);
- else
- generic_make_request(clone);
+ up(&io->notify);
}

static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
@@ -811,7 +799,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)

/* Encryption was already finished, submit io now */
if (crypt_finished) {
- kcryptd_crypt_write_io_submit(io, r, 0);
+ kcryptd_crypt_write_io_submit(io, r);

/*
* If there was an error, do not try next fragments.
@@ -909,13 +897,12 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
if (bio_data_dir(io->base_bio) == READ)
kcryptd_crypt_read_done(io, error);
else
- kcryptd_crypt_write_io_submit(io, error, 1);
+ kcryptd_crypt_write_io_submit(io, error);
}

static void kcryptd_crypt(struct work_struct *work)
{
struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
-
if (bio_data_dir(io->base_bio) == READ)
kcryptd_crypt_read_convert(io);
else
@@ -1005,8 +992,6 @@ static void crypt_dtr(struct dm_target *ti)
if (!cc)
return;

- if (cc->io_queue)
- destroy_workqueue(cc->io_queue);
if (cc->crypt_queue)
destroy_workqueue(cc->crypt_queue);

@@ -1252,11 +1237,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
cc->start = tmpll;

ret = -ENOMEM;
- cc->io_queue = create_singlethread_workqueue("kcryptd_io");
- if (!cc->io_queue) {
- ti->error = "Couldn't create kcryptd io queue";
- goto bad;
- }

cc->crypt_queue = create_singlethread_workqueue("kcryptd");
if (!cc->crypt_queue) {
@@ -1287,9 +1267,13 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
io = crypt_io_alloc(ti, bio, dm_target_offset(ti, bio->bi_sector));

if (bio_data_dir(io->base_bio) == READ)
- kcryptd_queue_io(io);
- else
+ kcryptd_io(io);
+ else {
+ sema_init(&io->notify, 0);
kcryptd_queue_crypt(io);
+ down(&io->notify);
+ kcryptd_io(io);
+ }

return DM_MAPIO_SUBMITTED;
}
--
1.7.2.3




--------------020505070807060200000005--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/