diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-08-29 22:13:13 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-08-29 22:13:13 -0400 |
commit | 07a3b417dc3d00802bd7b4874c3e811f0b015a7d (patch) | |
tree | b3b484067f700a70f3e7d575bad6e7e4ae2742cc | |
parent | b774ef491b4edf6876077014ecbb87f10c69c10f (diff) |
md/raid456: distribute raid processing over multiple cores
Now that the resources to handle stripe_head operations are allocated
percpu it is possible for raid5d to distribute stripe handling over
multiple cores. This conversion also adds a call to cond_resched() in
the non-multicore case to prevent one core from getting monopolized for
raid operations.
Cc: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/md/Kconfig | 11 | ||||
-rw-r--r-- | drivers/md/raid5.c | 36 |
2 files changed, 45 insertions, 2 deletions
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index abb8636bfde2..09c0c6e49ab5 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
@@ -154,6 +154,17 @@ config MD_RAID456 | |||
154 | 154 | ||
155 | If unsure, say Y. | 155 | If unsure, say Y. |
156 | 156 | ||
157 | config MULTICORE_RAID456 | ||
158 | bool "RAID-4/RAID-5/RAID-6 Multicore processing (EXPERIMENTAL)" | ||
159 | depends on MD_RAID456 | ||
160 | depends on SMP | ||
161 | depends on EXPERIMENTAL | ||
162 | ---help--- | ||
163 | Enable the raid456 module to dispatch per-stripe raid operations to a | ||
164 | thread pool. | ||
165 | |||
166 | If unsure, say N. | ||
167 | |||
157 | config MD_RAID6_PQ | 168 | config MD_RAID6_PQ |
158 | tristate | 169 | tristate |
159 | 170 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7c22e19aca82..364ea37706fa 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/kthread.h> | 47 | #include <linux/kthread.h> |
48 | #include <linux/raid/pq.h> | 48 | #include <linux/raid/pq.h> |
49 | #include <linux/async_tx.h> | 49 | #include <linux/async_tx.h> |
50 | #include <linux/async.h> | ||
50 | #include <linux/seq_file.h> | 51 | #include <linux/seq_file.h> |
51 | #include <linux/cpu.h> | 52 | #include <linux/cpu.h> |
52 | #include "md.h" | 53 | #include "md.h" |
@@ -4314,6 +4315,36 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) | |||
4314 | return handled; | 4315 | return handled; |
4315 | } | 4316 | } |
4316 | 4317 | ||
4318 | #ifdef CONFIG_MULTICORE_RAID456 | ||
4319 | static void __process_stripe(void *param, async_cookie_t cookie) | ||
4320 | { | ||
4321 | struct stripe_head *sh = param; | ||
4322 | |||
4323 | handle_stripe(sh); | ||
4324 | release_stripe(sh); | ||
4325 | } | ||
4326 | |||
4327 | static void process_stripe(struct stripe_head *sh, struct list_head *domain) | ||
4328 | { | ||
4329 | async_schedule_domain(__process_stripe, sh, domain); | ||
4330 | } | ||
4331 | |||
4332 | static void synchronize_stripe_processing(struct list_head *domain) | ||
4333 | { | ||
4334 | async_synchronize_full_domain(domain); | ||
4335 | } | ||
4336 | #else | ||
4337 | static void process_stripe(struct stripe_head *sh, struct list_head *domain) | ||
4338 | { | ||
4339 | handle_stripe(sh); | ||
4340 | release_stripe(sh); | ||
4341 | cond_resched(); | ||
4342 | } | ||
4343 | |||
4344 | static void synchronize_stripe_processing(struct list_head *domain) | ||
4345 | { | ||
4346 | } | ||
4347 | #endif | ||
4317 | 4348 | ||
4318 | 4349 | ||
4319 | /* | 4350 | /* |
@@ -4328,6 +4359,7 @@ static void raid5d(mddev_t *mddev) | |||
4328 | struct stripe_head *sh; | 4359 | struct stripe_head *sh; |
4329 | raid5_conf_t *conf = mddev_to_conf(mddev); | 4360 | raid5_conf_t *conf = mddev_to_conf(mddev); |
4330 | int handled; | 4361 | int handled; |
4362 | LIST_HEAD(raid_domain); | ||
4331 | 4363 | ||
4332 | pr_debug("+++ raid5d active\n"); | 4364 | pr_debug("+++ raid5d active\n"); |
4333 | 4365 | ||
@@ -4364,8 +4396,7 @@ static void raid5d(mddev_t *mddev) | |||
4364 | spin_unlock_irq(&conf->device_lock); | 4396 | spin_unlock_irq(&conf->device_lock); |
4365 | 4397 | ||
4366 | handled++; | 4398 | handled++; |
4367 | handle_stripe(sh); | 4399 | process_stripe(sh, &raid_domain); |
4368 | release_stripe(sh); | ||
4369 | 4400 | ||
4370 | spin_lock_irq(&conf->device_lock); | 4401 | spin_lock_irq(&conf->device_lock); |
4371 | } | 4402 | } |
@@ -4373,6 +4404,7 @@ static void raid5d(mddev_t *mddev) | |||
4373 | 4404 | ||
4374 | spin_unlock_irq(&conf->device_lock); | 4405 | spin_unlock_irq(&conf->device_lock); |
4375 | 4406 | ||
4407 | synchronize_stripe_processing(&raid_domain); | ||
4376 | async_tx_issue_pending_all(); | 4408 | async_tx_issue_pending_all(); |
4377 | unplug_slaves(mddev); | 4409 | unplug_slaves(mddev); |
4378 | 4410 | ||