[dm-devel] [PATCH 06/20] dm-crypt: Introduce an option that sets the number of threads.
Mikulas Patocka
mpatocka at redhat.com
Tue Aug 21 09:09:17 UTC 2012
Introduce an option "num_cpus". It allows the user to set the number of
threads used for encryption. The value "0" means a default.
The default is the number of CPUs in the system, but at most 3.
Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
---
drivers/md/dm-crypt.c | 96 ++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 76 insertions(+), 20 deletions(-)
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index b251e15..fd2909d 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -34,6 +34,8 @@
#define DMREQ_PULL_BATCH 16
#define DMREQ_PUSH_BATCH 16
+#define DM_CRYPT_DEFAULT_CPUS 3
+
/*
* context holding the current state of a multi-part conversion
*/
@@ -127,6 +129,7 @@ struct crypt_config {
struct workqueue_struct *io_queue;
struct workqueue_struct *crypt_queue;
unsigned crypt_threads_size;
+ int num_threads_value; /* the value entered in the arguments */
struct task_struct **crypt_threads;
wait_queue_head_t crypt_thread_wait;
@@ -1630,9 +1633,14 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct dm_arg_set as;
const char *opt_string;
char dummy;
+ int num_threads = -1;
static struct dm_arg _args[] = {
- {0, 1, "Invalid number of feature args"},
+ {0, INT_MAX, "Invalid number of feature args"},
+ };
+
+ static struct dm_arg num_cpu_arg[] = {
+ {0, 65536, "Number of CPUs"},
};
if (argc < 5) {
@@ -1716,18 +1724,31 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (ret)
goto bad;
- opt_string = dm_shift_arg(&as);
-
- if (opt_params == 1 && opt_string &&
- !strcasecmp(opt_string, "allow_discards"))
- ti->num_discard_requests = 1;
- else if (opt_params) {
- ret = -EINVAL;
- ti->error = "Invalid feature arguments";
- goto bad;
+ for (i = 0; i < opt_params; i++) {
+ opt_string = dm_shift_arg(&as);
+ if (!strcasecmp(opt_string, "allow_discards")) {
+ ti->num_discard_requests = 1;
+ } else if (!strcasecmp(opt_string, "num_cpus") && i + 1 < opt_params) {
+ ret = dm_read_arg(num_cpu_arg, &as, &num_threads, &ti->error);
+ if (ret)
+ goto bad;
+ i++;
+ } else {
+ ret = -EINVAL;
+ ti->error = "Invalid feature arguments";
+ goto bad;
+ }
}
}
+ cc->num_threads_value = num_threads;
+
+ if (num_threads <= 0) {
+ num_threads = num_online_cpus();
+ if (num_threads > DM_CRYPT_DEFAULT_CPUS)
+ num_threads = DM_CRYPT_DEFAULT_CPUS;
+ }
+
ret = -ENOMEM;
cc->io_queue = alloc_workqueue("kcryptd_io",
WQ_NON_REENTRANT|
@@ -1747,9 +1768,15 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad;
}
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i))
- cc->crypt_threads_size = i + 1;
+ if (num_threads == num_online_cpus()) {
+ for (i = 0; i < NR_CPUS; i++)
+ if (cpu_online(i))
+ cc->crypt_threads_size = i + 1;
+ } else {
+ if (num_threads > INT_MAX / sizeof(struct task_struct *))
+ num_threads = INT_MAX / sizeof(struct task_struct *);
+ cc->crypt_threads_size = num_threads;
+ }
init_waitqueue_head(&cc->crypt_thread_wait);
INIT_LIST_HEAD(&cc->crypt_thread_list);
@@ -1761,18 +1788,31 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad;
}
- for (i = 0; i < cc->crypt_threads_size; i++) {
- if (cpu_online(i)) {
- cc->crypt_threads[i] = kthread_create_on_node(
- dmcrypt_thread, cc, cpu_to_node(i),
- "dmcryptd/%d", i);
+ if (num_threads == num_online_cpus())
+ for (i = 0; i < cc->crypt_threads_size; i++) {
+ if (cpu_online(i)) {
+ cc->crypt_threads[i] = kthread_create_on_node(
+ dmcrypt_thread, cc, cpu_to_node(i),
+ "dmcryptd/%d", i);
+ if (IS_ERR(cc->crypt_threads[i])) {
+ ret = PTR_ERR(cc->crypt_threads[i]);
+ cc->crypt_threads[i] = NULL;
+ ti->error = "Couldn't spawn thread";
+ goto bad;
+ }
+ kthread_bind(cc->crypt_threads[i], i);
+ wake_up_process(cc->crypt_threads[i]);
+ }
+ } else {
+ for (i = 0; i < cc->crypt_threads_size; i++) {
+ cc->crypt_threads[i] = kthread_create(
+ dmcrypt_thread, cc, "dmcryptd/%d", i);
if (IS_ERR(cc->crypt_threads[i])) {
ret = PTR_ERR(cc->crypt_threads[i]);
cc->crypt_threads[i] = NULL;
ti->error = "Couldn't spawn thread";
goto bad;
}
- kthread_bind(cc->crypt_threads[i], i);
wake_up_process(cc->crypt_threads[i]);
}
}
@@ -1821,6 +1861,7 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
{
struct crypt_config *cc = ti->private;
unsigned int sz = 0;
+ unsigned int num_args;
switch (type) {
case STATUSTYPE_INFO:
@@ -1845,8 +1886,23 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
cc->dev->name, (unsigned long long)cc->start);
+ num_args = 0;
+ if (ti->num_discard_requests)
+ num_args++;
+
+ if (cc->num_threads_value >= 0)
+ num_args += 2;
+
+ if (!num_args)
+ break;
+
+ DMEMIT(" %u", num_args);
+
if (ti->num_discard_requests)
- DMEMIT(" 1 allow_discards");
+ DMEMIT(" allow_discards");
+
+ if (cc->num_threads_value >= 0)
+ DMEMIT(" num_cpus %d", cc->num_threads_value);
break;
}
--
1.7.10.4
More information about the dm-devel
mailing list