On Thu, Nov 12, 2009 at 05:00:05PM -0500, Chris Mason wrote:

[ ...]

> 
> The punch line is that the btrfs guy thinks we can solve all of this with
> just one more thread.  If we change dm-crypt to have a thread dedicated
> to sync IO and a thread dedicated to async IO the system should smooth
> out.

This is pretty likely to set your dm data on fire.  It's only for Mel
who starts his script w/mkfs.

It adds the second thread and more importantly makes sure the kcryptd
thread doesn't get stuck waiting for requests.

-chris

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index ed10381..295ffeb 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -94,6 +94,7 @@ struct crypt_config {
        struct bio_set *bs;
 
        struct workqueue_struct *io_queue;
+       struct workqueue_struct *async_io_queue;
        struct workqueue_struct *crypt_queue;
 
        /*
@@ -691,7 +692,10 @@ 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);
+       if (io->base_bio->bi_rw & (1 << BIO_RW_SYNCIO))
+               queue_work(cc->io_queue, &io->work);
+       else
+               queue_work(cc->async_io_queue, &io->work);
 }
 
 static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
@@ -759,8 +763,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, 1);
                        /*
                         * If there was an error, do not try next fragments.
                         * For async, error is processed in async handler.
@@ -1120,6 +1123,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int 
argc, char **argv)
        } else
                cc->iv_mode = NULL;
 
+       cc->async_io_queue = create_singlethread_workqueue("kcryptd_async_io");
+       if (!cc->async_io_queue) {
+               ti->error = "Couldn't create kcryptd io queue";
+               goto bad_async_io_queue;
+       }
+
        cc->io_queue = create_singlethread_workqueue("kcryptd_io");
        if (!cc->io_queue) {
                ti->error = "Couldn't create kcryptd io queue";
@@ -1139,6 +1148,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int 
argc, char **argv)
 bad_crypt_queue:
        destroy_workqueue(cc->io_queue);
 bad_io_queue:
+       destroy_workqueue(cc->async_io_queue);
+bad_async_io_queue:
        kfree(cc->iv_mode);
 bad_ivmode_string:
        dm_put_device(ti, cc->dev);
@@ -1166,6 +1177,7 @@ static void crypt_dtr(struct dm_target *ti)
        struct crypt_config *cc = (struct crypt_config *) ti->private;
 
        destroy_workqueue(cc->io_queue);
+       destroy_workqueue(cc->async_io_queue);
        destroy_workqueue(cc->crypt_queue);
 
        if (cc->req)
--
To unsubscribe from this list: send the line "unsubscribe kernel-testers" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to