diff options
author | yangerkun <yangerkun@huawei.com> | 2023-07-11 14:11:29 +0800 |
---|---|---|
committer | Mike Snitzer <snitzer@kernel.org> | 2024-04-16 11:34:47 -0400 |
commit | 2285e1496dc68787a626145cfb0904a1b6cc5501 (patch) | |
tree | 2bc6c5285399d2a942b647883420600b1ebaa9d4 /drivers/md | |
parent | 5268de78e1e61c828174cb2ac7d9c566a97cce69 (diff) | |
download | lwn-2285e1496dc68787a626145cfb0904a1b6cc5501.tar.gz lwn-2285e1496dc68787a626145cfb0904a1b6cc5501.zip |
dm-crypt: export sysfs of all workqueues
Once there is a heavy IO load, so many encrypt/decrypt work will occupy
all of the cpu, which may lead to the poor performance for other service.
So the improved visibility and controls over dm-crypt workqueues, as
was offered with commit a2b8b2d97567 ("dm crypt: export sysfs of
kcryptd workqueue"), seems necessary. By exporting dm-crypt's
workqueues in sysfs, the entry like cpumask/max_active and so on can
help us to limit the CPU usage for encrypt/decrypt work.
However, commit a2b8b2d97567 did not consider that DM table reload
will call .ctr before .dtr, so the reload for dm-crypt failed because
the same sysfs name was present. This was the original need for commit
48b0777cd93d ("Revert "dm crypt: export sysfs of kcryptd workqueue"").
Reintroduce the use of WQ_SYSFS, and use it for both the IO and crypt
workqueues, but make the workqueue names include a unique id (via ida)
to allow both old and new sysfs entries to coexist.
Signed-off-by: yangerkun <yangerkun@huawei.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-crypt.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index eabc576d8d28..5bfa35760167 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -47,6 +47,8 @@ #define DM_MSG_PREFIX "crypt" +static DEFINE_IDA(workqueue_ida); + /* * context holding the current state of a multi-part conversion */ @@ -184,6 +186,7 @@ struct crypt_config { struct crypto_aead **tfms_aead; } cipher_tfm; unsigned int tfms_count; + int workqueue_id; unsigned long cipher_flags; /* @@ -2771,6 +2774,9 @@ static void crypt_dtr(struct dm_target *ti) if (cc->crypt_queue) destroy_workqueue(cc->crypt_queue); + if (cc->workqueue_id) + ida_free(&workqueue_ida, cc->workqueue_id); + crypt_free_tfms(cc); bioset_exit(&cc->bs); @@ -3232,7 +3238,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) { struct crypt_config *cc; const char *devname = dm_table_device_name(ti->table); - int key_size; + int key_size, wq_id; unsigned int align_mask; unsigned int common_wq_flags; unsigned long long tmpll; @@ -3401,25 +3407,33 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->tag_pool_max_sectors <<= cc->sector_shift; } + wq_id = ida_alloc_min(&workqueue_ida, 1, GFP_KERNEL); + if (wq_id < 0) { + ti->error = "Couldn't get workqueue id"; + ret = wq_id; + goto bad; + } + cc->workqueue_id = wq_id; + ret = -ENOMEM; - common_wq_flags = WQ_MEM_RECLAIM; + common_wq_flags = WQ_MEM_RECLAIM | WQ_SYSFS; if (test_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags)) common_wq_flags |= WQ_HIGHPRI; - cc->io_queue = alloc_workqueue("kcryptd_io/%s", common_wq_flags, 1, devname); + cc->io_queue = alloc_workqueue("kcryptd_io-%s-%d", common_wq_flags, 1, devname, wq_id); if (!cc->io_queue) { ti->error = "Couldn't create kcryptd io queue"; goto bad; } if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) { - cc->crypt_queue = alloc_workqueue("kcryptd/%s", + cc->crypt_queue = alloc_workqueue("kcryptd-%s-%d", common_wq_flags | WQ_CPU_INTENSIVE, - 1, devname); + 1, devname, wq_id); } else { - cc->crypt_queue = alloc_workqueue("kcryptd/%s", + cc->crypt_queue = alloc_workqueue("kcryptd-%s-%d", common_wq_flags | WQ_CPU_INTENSIVE | WQ_UNBOUND, - num_online_cpus(), devname); + num_online_cpus(), devname, wq_id); } if (!cc->crypt_queue) { ti->error = "Couldn't create kcryptd queue"; |