Make it possible to disable offloading writes by setting the optional
'submit_from_crypt_cpus' table argument.
There are some situations where offloading write bios from the
encryption threads to a single thread degrades performance
significantly.
The default is to offload write bios to the same thread because it
benefits CFQ to have writes submitted using the same IO context.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Otherwise #opt_params is the number of following arguments.
Example of optional parameters section:
Otherwise #opt_params is the number of following arguments.
Example of optional parameters section:
- 2 allow_discards same_cpu_crypt
+ 3 allow_discards same_cpu_crypt submit_from_crypt_cpus
allow_discards
Block discard requests (a.k.a. TRIM) are passed through the crypt device.
allow_discards
Block discard requests (a.k.a. TRIM) are passed through the crypt device.
The default is to use an unbound workqueue so that encryption work
is automatically balanced between available CPUs.
The default is to use an unbound workqueue so that encryption work
is automatically balanced between available CPUs.
+submit_from_crypt_cpus
+ Disable offloading writes to a separate thread after encryption.
+ There are some situations where offloading write bios from the
+ encryption threads to a single thread degrades performance
+ significantly. The default is to offload write bios to the same
+ thread because it benefits CFQ to have writes submitted using the
+ same context.
+
Example scripts
===============
LUKS (Linux Unified Key Setup) is now the preferred way to set up disk
Example scripts
===============
LUKS (Linux Unified Key Setup) is now the preferred way to set up disk
* Crypt: maps a linear range of a block device
* and encrypts / decrypts at the same time.
*/
* Crypt: maps a linear range of a block device
* and encrypts / decrypts at the same time.
*/
-enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, DM_CRYPT_SAME_CPU };
+enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
+ DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
/*
* The fields in here must be read only after initialization.
/*
* The fields in here must be read only after initialization.
clone->bi_iter.bi_sector = cc->start + io->sector;
clone->bi_iter.bi_sector = cc->start + io->sector;
+ if (likely(!async) && test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags)) {
+ generic_make_request(clone);
+ return;
+ }
+
spin_lock_irqsave(&cc->write_thread_wait.lock, flags);
list_add_tail(&io->list, &cc->write_thread_list);
wake_up_locked(&cc->write_thread_wait);
spin_lock_irqsave(&cc->write_thread_wait.lock, flags);
list_add_tail(&io->list, &cc->write_thread_list);
wake_up_locked(&cc->write_thread_wait);
char dummy;
static struct dm_arg _args[] = {
char dummy;
static struct dm_arg _args[] = {
- {0, 2, "Invalid number of feature args"},
+ {0, 3, "Invalid number of feature args"},
else if (!strcasecmp(opt_string, "same_cpu_crypt"))
set_bit(DM_CRYPT_SAME_CPU, &cc->flags);
else if (!strcasecmp(opt_string, "same_cpu_crypt"))
set_bit(DM_CRYPT_SAME_CPU, &cc->flags);
+ else if (!strcasecmp(opt_string, "submit_from_crypt_cpus"))
+ set_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
+
else {
ti->error = "Invalid feature arguments";
goto bad;
else {
ti->error = "Invalid feature arguments";
goto bad;
num_feature_args += !!ti->num_discard_bios;
num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags);
num_feature_args += !!ti->num_discard_bios;
num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags);
+ num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
if (num_feature_args) {
DMEMIT(" %d", num_feature_args);
if (ti->num_discard_bios)
DMEMIT(" allow_discards");
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
DMEMIT(" same_cpu_crypt");
if (num_feature_args) {
DMEMIT(" %d", num_feature_args);
if (ti->num_discard_bios)
DMEMIT(" allow_discards");
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
DMEMIT(" same_cpu_crypt");
+ if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags))
+ DMEMIT(" submit_from_crypt_cpus");