Skip to content

Commit 5268de7

Browse files
Mikulas PatockaMike Snitzer
authored andcommitted
dm-crypt: add the optional "high_priority" flag
When WQ_HIGHPRI was used for the dm-crypt kcryptd workqueue it was reported that dm-crypt performs badly when the system is loaded[1]. Because of reports of audio skipping, dm-crypt stopped using WQ_HIGHPRI with commit f612b21 (Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues"). But it has since been determined that WQ_HIGHPRI provides improved performance (with reduced latency) for highend systems with much more resources than those laptop/desktop users which suffered from the use of WQ_HIGHPRI. As such, add an option "high_priority" that allows the use of WQ_HIGHPRI for dm-crypt's workqueues and also sets the write_thread to nice level MIN_NICE (-20). This commit makes it optional, so that normal users won't be harmed by it. [1] https://listman.redhat.com/archives/dm-devel/2023-February/053410.html Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
1 parent 48ef0ba commit 5268de7

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

Documentation/admin-guide/device-mapper/dm-crypt.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ same_cpu_crypt
113113
The default is to use an unbound workqueue so that encryption work
114114
is automatically balanced between available CPUs.
115115

116+
high_priority
117+
Set dm-crypt workqueues and the writer thread to high priority. This
118+
improves throughput and latency of dm-crypt while degrading general
119+
responsiveness of the system.
120+
116121
submit_from_crypt_cpus
117122
Disable offloading writes to a separate thread after encryption.
118123
There are some situations where offloading write bios from the

drivers/md/dm-crypt.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ struct iv_elephant_private {
137137
* and encrypts / decrypts at the same time.
138138
*/
139139
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
140-
DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
141-
DM_CRYPT_NO_READ_WORKQUEUE, DM_CRYPT_NO_WRITE_WORKQUEUE,
142-
DM_CRYPT_WRITE_INLINE };
140+
DM_CRYPT_SAME_CPU, DM_CRYPT_HIGH_PRIORITY,
141+
DM_CRYPT_NO_OFFLOAD, DM_CRYPT_NO_READ_WORKQUEUE,
142+
DM_CRYPT_NO_WRITE_WORKQUEUE, DM_CRYPT_WRITE_INLINE };
143143

144144
enum cipher_flags {
145145
CRYPT_MODE_INTEGRITY_AEAD, /* Use authenticated mode for cipher */
@@ -3134,7 +3134,7 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar
31343134
struct crypt_config *cc = ti->private;
31353135
struct dm_arg_set as;
31363136
static const struct dm_arg _args[] = {
3137-
{0, 8, "Invalid number of feature args"},
3137+
{0, 9, "Invalid number of feature args"},
31383138
};
31393139
unsigned int opt_params, val;
31403140
const char *opt_string, *sval;
@@ -3161,6 +3161,8 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar
31613161

31623162
else if (!strcasecmp(opt_string, "same_cpu_crypt"))
31633163
set_bit(DM_CRYPT_SAME_CPU, &cc->flags);
3164+
else if (!strcasecmp(opt_string, "high_priority"))
3165+
set_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags);
31643166

31653167
else if (!strcasecmp(opt_string, "submit_from_crypt_cpus"))
31663168
set_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
@@ -3232,6 +3234,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
32323234
const char *devname = dm_table_device_name(ti->table);
32333235
int key_size;
32343236
unsigned int align_mask;
3237+
unsigned int common_wq_flags;
32353238
unsigned long long tmpll;
32363239
int ret;
32373240
size_t iv_size_padding, additional_req_size;
@@ -3399,19 +3402,25 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
33993402
}
34003403

34013404
ret = -ENOMEM;
3402-
cc->io_queue = alloc_workqueue("kcryptd_io/%s", WQ_MEM_RECLAIM, 1, devname);
3405+
common_wq_flags = WQ_MEM_RECLAIM;
3406+
if (test_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags))
3407+
common_wq_flags |= WQ_HIGHPRI;
3408+
3409+
cc->io_queue = alloc_workqueue("kcryptd_io/%s", common_wq_flags, 1, devname);
34033410
if (!cc->io_queue) {
34043411
ti->error = "Couldn't create kcryptd io queue";
34053412
goto bad;
34063413
}
34073414

3408-
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
3409-
cc->crypt_queue = alloc_workqueue("kcryptd/%s", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM,
3415+
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) {
3416+
cc->crypt_queue = alloc_workqueue("kcryptd/%s",
3417+
common_wq_flags | WQ_CPU_INTENSIVE,
34103418
1, devname);
3411-
else
3419+
} else {
34123420
cc->crypt_queue = alloc_workqueue("kcryptd/%s",
3413-
WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND,
3421+
common_wq_flags | WQ_CPU_INTENSIVE | WQ_UNBOUND,
34143422
num_online_cpus(), devname);
3423+
}
34153424
if (!cc->crypt_queue) {
34163425
ti->error = "Couldn't create kcryptd queue";
34173426
goto bad;
@@ -3427,6 +3436,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
34273436
ti->error = "Couldn't spawn write thread";
34283437
goto bad;
34293438
}
3439+
if (test_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags))
3440+
set_user_nice(cc->write_thread, MIN_NICE);
34303441

34313442
ti->num_flush_bios = 1;
34323443
ti->limit_swap_bios = true;
@@ -3547,6 +3558,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
35473558

35483559
num_feature_args += !!ti->num_discard_bios;
35493560
num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags);
3561+
num_feature_args += test_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags);
35503562
num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
35513563
num_feature_args += test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags);
35523564
num_feature_args += test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags);
@@ -3560,6 +3572,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
35603572
DMEMIT(" allow_discards");
35613573
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
35623574
DMEMIT(" same_cpu_crypt");
3575+
if (test_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags))
3576+
DMEMIT(" high_priority");
35633577
if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags))
35643578
DMEMIT(" submit_from_crypt_cpus");
35653579
if (test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags))
@@ -3579,6 +3593,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
35793593
DMEMIT_TARGET_NAME_VERSION(ti->type);
35803594
DMEMIT(",allow_discards=%c", ti->num_discard_bios ? 'y' : 'n');
35813595
DMEMIT(",same_cpu_crypt=%c", test_bit(DM_CRYPT_SAME_CPU, &cc->flags) ? 'y' : 'n');
3596+
DMEMIT(",high_priority=%c", test_bit(DM_CRYPT_HIGH_PRIORITY, &cc->flags) ? 'y' : 'n');
35823597
DMEMIT(",submit_from_crypt_cpus=%c", test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags) ?
35833598
'y' : 'n');
35843599
DMEMIT(",no_read_workqueue=%c", test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags) ?
@@ -3706,7 +3721,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
37063721

37073722
static struct target_type crypt_target = {
37083723
.name = "crypt",
3709-
.version = {1, 25, 0},
3724+
.version = {1, 26, 0},
37103725
.module = THIS_MODULE,
37113726
.ctr = crypt_ctr,
37123727
.dtr = crypt_dtr,

0 commit comments

Comments
 (0)