aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorShaohua Li <shli@kernel.org>2012-08-01 18:33:15 -0400
committerNeilBrown <neilb@suse.de>2012-08-01 18:33:15 -0400
commit46a06401f6ba13e59d24746fa9ffa6773b69eee3 (patch)
treef6d938b79aed14b7a51cda5a607e09f8226feb03 /drivers/md/raid5.c
parent8811b5968f6216e97ccb9fe7b9883af39e339921 (diff)
raid5: raid5d handle stripe in batch way
Let raid5d handle stripe in batch way to reduce conf->device_lock locking. Signed-off-by: Shaohua Li <shli@fusionio.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 978ba9b7a3c4..9e41ae37bd40 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4574,6 +4574,30 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio)
4574 return handled; 4574 return handled;
4575} 4575}
4576 4576
4577#define MAX_STRIPE_BATCH 8
4578static int handle_active_stripes(struct r5conf *conf)
4579{
4580 struct stripe_head *batch[MAX_STRIPE_BATCH], *sh;
4581 int i, batch_size = 0;
4582
4583 while (batch_size < MAX_STRIPE_BATCH &&
4584 (sh = __get_priority_stripe(conf)) != NULL)
4585 batch[batch_size++] = sh;
4586
4587 if (batch_size == 0)
4588 return batch_size;
4589 spin_unlock_irq(&conf->device_lock);
4590
4591 for (i = 0; i < batch_size; i++)
4592 handle_stripe(batch[i]);
4593
4594 cond_resched();
4595
4596 spin_lock_irq(&conf->device_lock);
4597 for (i = 0; i < batch_size; i++)
4598 __release_stripe(conf, batch[i]);
4599 return batch_size;
4600}
4577 4601
4578/* 4602/*
4579 * This is our raid5 kernel thread. 4603 * This is our raid5 kernel thread.
@@ -4584,7 +4608,6 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio)
4584 */ 4608 */
4585static void raid5d(struct mddev *mddev) 4609static void raid5d(struct mddev *mddev)
4586{ 4610{
4587 struct stripe_head *sh;
4588 struct r5conf *conf = mddev->private; 4611 struct r5conf *conf = mddev->private;
4589 int handled; 4612 int handled;
4590 struct blk_plug plug; 4613 struct blk_plug plug;
@@ -4598,6 +4621,7 @@ static void raid5d(struct mddev *mddev)
4598 spin_lock_irq(&conf->device_lock); 4621 spin_lock_irq(&conf->device_lock);
4599 while (1) { 4622 while (1) {
4600 struct bio *bio; 4623 struct bio *bio;
4624 int batch_size;
4601 4625
4602 if ( 4626 if (
4603 !list_empty(&conf->bitmap_list)) { 4627 !list_empty(&conf->bitmap_list)) {
@@ -4621,21 +4645,16 @@ static void raid5d(struct mddev *mddev)
4621 handled++; 4645 handled++;
4622 } 4646 }
4623 4647
4624 sh = __get_priority_stripe(conf); 4648 batch_size = handle_active_stripes(conf);
4625 4649 if (!batch_size)
4626 if (!sh)
4627 break; 4650 break;
4628 spin_unlock_irq(&conf->device_lock); 4651 handled += batch_size;
4629
4630 handled++;
4631 handle_stripe(sh);
4632 release_stripe(sh);
4633 cond_resched();
4634 4652
4635 if (mddev->flags & ~(1<<MD_CHANGE_PENDING)) 4653 if (mddev->flags & ~(1<<MD_CHANGE_PENDING)) {
4654 spin_unlock_irq(&conf->device_lock);
4636 md_check_recovery(mddev); 4655 md_check_recovery(mddev);
4637 4656 spin_lock_irq(&conf->device_lock);
4638 spin_lock_irq(&conf->device_lock); 4657 }
4639 } 4658 }
4640 pr_debug("%d stripes handled\n", handled); 4659 pr_debug("%d stripes handled\n", handled);
4641 4660