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 /drivers/md | |
| 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>
Diffstat (limited to 'drivers/md')
| -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 | ||
