Skip to content

Commit f3396c5

Browse files
Mikulas Patockasnitm
authored andcommitted
dm crypt: use unbound workqueue for request processing
Use unbound workqueue by default so that work is automatically balanced between available CPUs. The original behavior of encrypting using the same cpu that IO was submitted on can still be enabled by setting the optional 'same_cpu_crypt' table argument. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent 37527b8 commit f3396c5

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

Documentation/device-mapper/dm-crypt.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Parameters: <cipher> <key> <iv_offset> <device path> \
5151
Otherwise #opt_params is the number of following arguments.
5252

5353
Example of optional parameters section:
54-
1 allow_discards
54+
2 allow_discards same_cpu_crypt
5555

5656
allow_discards
5757
Block discard requests (a.k.a. TRIM) are passed through the crypt device.
@@ -63,6 +63,11 @@ allow_discards
6363
used space etc.) if the discarded blocks can be located easily on the
6464
device later.
6565

66+
same_cpu_crypt
67+
Perform encryption using the same cpu that IO was submitted on.
68+
The default is to use an unbound workqueue so that encryption work
69+
is automatically balanced between available CPUs.
70+
6671
Example scripts
6772
===============
6873
LUKS (Linux Unified Key Setup) is now the preferred way to set up disk

drivers/md/dm-crypt.c

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ struct iv_tcw_private {
108108
* Crypt: maps a linear range of a block device
109109
* and encrypts / decrypts at the same time.
110110
*/
111-
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID };
111+
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, DM_CRYPT_SAME_CPU };
112112

113113
/*
114114
* The fields in here must be read only after initialization.
@@ -1688,7 +1688,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
16881688
char dummy;
16891689

16901690
static struct dm_arg _args[] = {
1691-
{0, 1, "Invalid number of feature args"},
1691+
{0, 2, "Invalid number of feature args"},
16921692
};
16931693

16941694
if (argc < 5) {
@@ -1788,15 +1788,23 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
17881788
if (ret)
17891789
goto bad;
17901790

1791-
opt_string = dm_shift_arg(&as);
1791+
while (opt_params--) {
1792+
opt_string = dm_shift_arg(&as);
1793+
if (!opt_string) {
1794+
ti->error = "Not enough feature arguments";
1795+
goto bad;
1796+
}
17921797

1793-
if (opt_params == 1 && opt_string &&
1794-
!strcasecmp(opt_string, "allow_discards"))
1795-
ti->num_discard_bios = 1;
1796-
else if (opt_params) {
1797-
ret = -EINVAL;
1798-
ti->error = "Invalid feature arguments";
1799-
goto bad;
1798+
if (!strcasecmp(opt_string, "allow_discards"))
1799+
ti->num_discard_bios = 1;
1800+
1801+
else if (!strcasecmp(opt_string, "same_cpu_crypt"))
1802+
set_bit(DM_CRYPT_SAME_CPU, &cc->flags);
1803+
1804+
else {
1805+
ti->error = "Invalid feature arguments";
1806+
goto bad;
1807+
}
18001808
}
18011809
}
18021810

@@ -1807,8 +1815,11 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
18071815
goto bad;
18081816
}
18091817

1810-
cc->crypt_queue = alloc_workqueue("kcryptd",
1811-
WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 1);
1818+
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
1819+
cc->crypt_queue = alloc_workqueue("kcryptd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 1);
1820+
else
1821+
cc->crypt_queue = alloc_workqueue("kcryptd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND,
1822+
num_online_cpus());
18121823
if (!cc->crypt_queue) {
18131824
ti->error = "Couldn't create kcryptd queue";
18141825
goto bad;
@@ -1860,6 +1871,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
18601871
{
18611872
struct crypt_config *cc = ti->private;
18621873
unsigned i, sz = 0;
1874+
int num_feature_args = 0;
18631875

18641876
switch (type) {
18651877
case STATUSTYPE_INFO:
@@ -1878,8 +1890,15 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
18781890
DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
18791891
cc->dev->name, (unsigned long long)cc->start);
18801892

1881-
if (ti->num_discard_bios)
1882-
DMEMIT(" 1 allow_discards");
1893+
num_feature_args += !!ti->num_discard_bios;
1894+
num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags);
1895+
if (num_feature_args) {
1896+
DMEMIT(" %d", num_feature_args);
1897+
if (ti->num_discard_bios)
1898+
DMEMIT(" allow_discards");
1899+
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
1900+
DMEMIT(" same_cpu_crypt");
1901+
}
18831902

18841903
break;
18851904
}
@@ -1976,7 +1995,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
19761995

19771996
static struct target_type crypt_target = {
19781997
.name = "crypt",
1979-
.version = {1, 13, 0},
1998+
.version = {1, 14, 0},
19801999
.module = THIS_MODULE,
19812000
.ctr = crypt_ctr,
19822001
.dtr = crypt_dtr,

0 commit comments

Comments
 (0)