Commit 9934a8be authored by Milan Broz's avatar Milan Broz Committed by Alasdair G Kergon

dm crypt: use per device singlethread workqueues

Use a separate single-threaded workqueue for each crypt device
instead of one global workqueue.
Signed-off-by: default avatarMilan Broz <mbroz@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent d336416f
...@@ -80,6 +80,7 @@ struct crypt_config { ...@@ -80,6 +80,7 @@ struct crypt_config {
mempool_t *page_pool; mempool_t *page_pool;
struct bio_set *bs; struct bio_set *bs;
struct workqueue_struct *queue;
/* /*
* crypto related data * crypto related data
*/ */
...@@ -480,13 +481,14 @@ static void dec_pending(struct dm_crypt_io *io, int error) ...@@ -480,13 +481,14 @@ static void dec_pending(struct dm_crypt_io *io, int error)
* Needed because it would be very unwise to do decryption in an * Needed because it would be very unwise to do decryption in an
* interrupt context. * interrupt context.
*/ */
static struct workqueue_struct *_kcryptd_workqueue;
static void kcryptd_do_work(struct work_struct *work); static void kcryptd_do_work(struct work_struct *work);
static void kcryptd_queue_io(struct dm_crypt_io *io) static void kcryptd_queue_io(struct dm_crypt_io *io)
{ {
struct crypt_config *cc = io->target->private;
INIT_WORK(&io->work, kcryptd_do_work); INIT_WORK(&io->work, kcryptd_do_work);
queue_work(_kcryptd_workqueue, &io->work); queue_work(cc->queue, &io->work);
} }
static void crypt_endio(struct bio *clone, int error) static void crypt_endio(struct bio *clone, int error)
...@@ -868,9 +870,17 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -868,9 +870,17 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
} else } else
cc->iv_mode = NULL; cc->iv_mode = NULL;
cc->queue = create_singlethread_workqueue("kcryptd");
if (!cc->queue) {
ti->error = "Couldn't create kcryptd queue";
goto bad_queue;
}
ti->private = cc; ti->private = cc;
return 0; return 0;
bad_queue:
kfree(cc->iv_mode);
bad_iv_mode: bad_iv_mode:
dm_put_device(ti, cc->dev); dm_put_device(ti, cc->dev);
bad5: bad5:
...@@ -895,7 +905,7 @@ static void crypt_dtr(struct dm_target *ti) ...@@ -895,7 +905,7 @@ static void crypt_dtr(struct dm_target *ti)
{ {
struct crypt_config *cc = (struct crypt_config *) ti->private; struct crypt_config *cc = (struct crypt_config *) ti->private;
flush_workqueue(_kcryptd_workqueue); destroy_workqueue(cc->queue);
bioset_free(cc->bs); bioset_free(cc->bs);
mempool_destroy(cc->page_pool); mempool_destroy(cc->page_pool);
...@@ -1040,25 +1050,12 @@ static int __init dm_crypt_init(void) ...@@ -1040,25 +1050,12 @@ static int __init dm_crypt_init(void)
if (!_crypt_io_pool) if (!_crypt_io_pool)
return -ENOMEM; return -ENOMEM;
_kcryptd_workqueue = create_workqueue("kcryptd");
if (!_kcryptd_workqueue) {
r = -ENOMEM;
DMERR("couldn't create kcryptd");
goto bad1;
}
r = dm_register_target(&crypt_target); r = dm_register_target(&crypt_target);
if (r < 0) { if (r < 0) {
DMERR("register failed %d", r); DMERR("register failed %d", r);
goto bad2; kmem_cache_destroy(_crypt_io_pool);
} }
return 0;
bad2:
destroy_workqueue(_kcryptd_workqueue);
bad1:
kmem_cache_destroy(_crypt_io_pool);
return r; return r;
} }
...@@ -1069,7 +1066,6 @@ static void __exit dm_crypt_exit(void) ...@@ -1069,7 +1066,6 @@ static void __exit dm_crypt_exit(void)
if (r < 0) if (r < 0)
DMERR("unregister failed %d", r); DMERR("unregister failed %d", r);
destroy_workqueue(_kcryptd_workqueue);
kmem_cache_destroy(_crypt_io_pool); kmem_cache_destroy(_crypt_io_pool);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment