summary refs log tree commit diff
path: root/drivers/md/raid5.h
diff options
context:
space:
mode:
authorYuanhan Liu <yuanhan.liu@linux.intel.com>2015-05-08 18:19:06 +1000
committerNeilBrown <neilb@suse.de>2015-06-17 10:00:21 +1000
commitb1b4648648e18775082858eca2517322f63e57a1 (patch)
tree1736c4ffb57d741562e9f2e56ded963a7dcaa194 /drivers/md/raid5.h
parent9f3520c3115b451ac1301779fc3c769d94907a70 (diff)
downloadlinux-b1b4648648e18775082858eca2517322f63e57a1.tar.gz
md/raid5: split wait_for_stripe and introduce wait_for_quiescent
I noticed heavy spin lock contention at get_active_stripe(), introduced
at being wake up stage, where a bunch of processes try to re-hold the
spin lock again.

After giving some thoughts on this issue, I found the lock could be
relieved(and even avoided) if we turn the wait_for_stripe to per
waitqueue for each lock hash and make the wake up exclusive: wake up
one process each time, which avoids the lock contention naturally.

Before go hacking with wait_for_stripe, I found it actually has 2
usages: for the array to enter or leave the quiescent state, and also
to wait for an available stripe in each of the hash lists.

So this patch splits the first usage off into a separate wait_queue,
wait_for_quiescent, and the next patch will turn the second usage into
one waitqueue for each hash value, and make it exclusive, to relieve
the lock contention.

v2: wake_up(wait_for_quiescent) when (active_stripes == 0)
    Commit log refactor suggestion from Neil.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.h')
-rw-r--r--drivers/md/raid5.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 896d603ad0da..9b84b8820fc5 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -511,6 +511,7 @@ struct r5conf {
 	struct list_head	inactive_list[NR_STRIPE_HASH_LOCKS];
 	atomic_t		empty_inactive_list_nr;
 	struct llist_head	released_stripes;
+	wait_queue_head_t	wait_for_quiescent;
 	wait_queue_head_t	wait_for_stripe;
 	wait_queue_head_t	wait_for_overlap;
 	unsigned long		cache_state;