From: Lai Jiangshan <laijs@cn.fujitsu.com>
To: paulmck@linux.vnet.ibm.com
Cc: linux-kernel@vger.kernel.org, mingo@elte.hu, dipankar@in.ibm.com,
akpm@linux-foundation.org, mathieu.desnoyers@polymtl.ca,
josh@joshtriplett.org, niv@us.ibm.com, tglx@linutronix.de,
peterz@infradead.org, rostedt@goodmis.org,
Valdis.Kletnieks@vt.edu, dhowells@redhat.com,
eric.dumazet@gmail.com, darren@dvhart.com, fweisbec@gmail.com,
patches@linaro.org
Subject: [PATCH 1/2 RFC] srcu: change the comments of the wait algorithm
Date: Mon, 27 Feb 2012 16:01:00 +0800 [thread overview]
Message-ID: <4F4B383C.1000804@cn.fujitsu.com> (raw)
In-Reply-To: <20120224200109.GH2399@linux.vnet.ibm.com>
Hi, ALL
The call_srcu() will be sent soon(may be in 2 days). I found something is not
good in current sruc when I implement it, so I do more prepare for it.
The second patch is inspired Peter. I had decided to use per-cpu machine,
the the snap array makes me unhappy. If a machine is sleeping/preempted
while checking, the other machine can't not check the same srcu_struct.
It is nothing big, but it also blocks the sychronize_srcu_expedited().
I hope sychronize_srcu_expedited() can't be blocked when it try to do its
fast-checking. So I try to find non-block checking algorithm, and I find
Peter's.
The most things in these two patches are comments, so I bring a lot
troubles to Paul because my poor English.
Thanks,
Lai
>From 77af819872ddab065d3a46758471b80f31b30e5e Mon Sep 17 00:00:00 2001
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Mon, 27 Feb 2012 10:52:00 +0800
Subject: [PATCH 1/2] srcu: change the comments of the wait algorithm
The original comments does not describe the essential of the wait algorithm
well.
The safe of srcu-protected data and srcu critical section is provided by
wait_idx(), not the flipping.
The two index of the active counter array and the flipping are just used to keep
the wait_idx() from starvation.
(the flip also provides "only one srcu_read_lock() at most after flip
for every cpu", this coupling will be remove in future(next patch))
The code will be split as pieces between every machine-states for call_srcu(),
It is very hard to provide the exactly semantics as original comments,
So I have to consider the exactly what the algorithm, and I change this
comments.
The code is not changed, but it is refactored a little.
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
kernel/srcu.c | 75 +++++++++++++++++++++++++++++----------------------------
1 files changed, 38 insertions(+), 37 deletions(-)
diff --git a/kernel/srcu.c b/kernel/srcu.c
index b6b9ea2..47ee35d 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -249,6 +249,10 @@ EXPORT_SYMBOL_GPL(__srcu_read_unlock);
*/
#define SYNCHRONIZE_SRCU_READER_DELAY 5
+/*
+ * Wait until all the readers(which starts before this wait_idx()
+ * with the specified idx) complete.
+ */
static void wait_idx(struct srcu_struct *sp, int idx, bool expedited)
{
int trycount = 0;
@@ -291,24 +295,9 @@ static void wait_idx(struct srcu_struct *sp, int idx, bool expedited)
smp_mb(); /* E */
}
-/*
- * Flip the readers' index by incrementing ->completed, then wait
- * until there are no more readers using the counters referenced by
- * the old index value. (Recall that the index is the bottom bit
- * of ->completed.)
- *
- * Of course, it is possible that a reader might be delayed for the
- * full duration of flip_idx_and_wait() between fetching the
- * index and incrementing its counter. This possibility is handled
- * by the next __synchronize_srcu() invoking wait_idx() for such readers
- * before starting a new grace period.
- */
-static void flip_idx_and_wait(struct srcu_struct *sp, bool expedited)
+static void srcu_flip(struct srcu_struct *sp)
{
- int idx;
-
- idx = sp->completed++ & 0x1;
- wait_idx(sp, idx, expedited);
+ sp->completed++;
}
/*
@@ -316,6 +305,8 @@ static void flip_idx_and_wait(struct srcu_struct *sp, bool expedited)
*/
static void __synchronize_srcu(struct srcu_struct *sp, bool expedited)
{
+ int busy_idx;
+
rcu_lockdep_assert(!lock_is_held(&sp->dep_map) &&
!lock_is_held(&rcu_bh_lock_map) &&
!lock_is_held(&rcu_lock_map) &&
@@ -323,8 +314,31 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool expedited)
"Illegal synchronize_srcu() in same-type SRCU (or RCU) read-side critical section");
mutex_lock(&sp->mutex);
+ busy_idx = sp->completed & 0X1UL;
/*
+ * There are some readers start with idx=0, and some others start
+ * with idx=1. So two wait_idx()s are enough for synchronize:
+ * __synchronize_srcu() {
+ * wait_idx(sp, 0, expedited);
+ * wait_idx(sp, 1, expedited);
+ * }
+ * When it returns, all started readers have complete.
+ *
+ * But synchronizer may be starved by the readers, example,
+ * if sp->complete & 0x1L == 1, wait_idx(sp, 1, expedited)
+ * may not returns if there are continuous readers start
+ * with idx=1.
+ *
+ * So we need to flip the busy index to keep synchronizer
+ * from starvation.
+ */
+
+ /*
+ * The above comments assume we have readers with all the
+ * 2 idx. It does have this probability, some readers may
+ * hold the reader lock with idx=1-busy_idx:
+ *
* Suppose that during the previous grace period, a reader
* picked up the old value of the index, but did not increment
* its counter until after the previous instance of
@@ -333,31 +347,18 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool expedited)
* not start until after the grace period started, so the grace
* period was not obligated to wait for that reader.
*
- * However, the current SRCU grace period does have to wait for
- * that reader. This is handled by invoking wait_idx() on the
- * non-active set of counters (hence sp->completed - 1). Once
- * wait_idx() returns, we know that all readers that picked up
- * the old value of ->completed and that already incremented their
- * counter will have completed.
- *
- * But what about readers that picked up the old value of
- * ->completed, but -still- have not managed to increment their
- * counter? We do not need to wait for those readers, because
- * they will have started their SRCU read-side critical section
- * after the current grace period starts.
- *
- * Because it is unlikely that readers will be preempted between
- * fetching ->completed and incrementing their counter, wait_idx()
+ * Because this probability is not high, wait_idx()
* will normally not need to wait.
*/
- wait_idx(sp, (sp->completed - 1) & 0x1, expedited);
+ wait_idx(sp, 1 - busy_idx, expedited);
+
+ /* flip the index to ensure the return of the next wait_idx() */
+ srcu_flip(sp);
/*
- * Now that wait_idx() has waited for the really old readers,
- * invoke flip_idx_and_wait() to flip the counter and wait
- * for current SRCU readers.
+ * Now that wait_idx() has waited for the really old readers.
*/
- flip_idx_and_wait(sp, expedited);
+ wait_idx(sp, busy_idx, expedited);
mutex_unlock(&sp->mutex);
}
--
1.7.4.4
next prev parent reply other threads:[~2012-02-27 7:56 UTC|newest]
Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-13 2:09 [PATCH RFC tip/core/rcu] rcu: direct algorithmic SRCU implementation Paul E. McKenney
2012-02-15 12:59 ` Peter Zijlstra
2012-02-16 6:35 ` Paul E. McKenney
2012-02-16 10:50 ` Mathieu Desnoyers
2012-02-16 10:52 ` Peter Zijlstra
2012-02-16 11:14 ` Mathieu Desnoyers
2012-02-15 14:31 ` Mathieu Desnoyers
2012-02-15 14:51 ` Mathieu Desnoyers
2012-02-16 6:38 ` Paul E. McKenney
2012-02-16 11:00 ` Mathieu Desnoyers
2012-02-16 11:51 ` Peter Zijlstra
2012-02-16 12:18 ` Mathieu Desnoyers
2012-02-16 12:44 ` Peter Zijlstra
2012-02-16 14:52 ` Mathieu Desnoyers
2012-02-16 14:58 ` Peter Zijlstra
2012-02-16 15:13 ` Paul E. McKenney
2012-02-20 7:15 ` Lai Jiangshan
2012-02-20 17:44 ` Paul E. McKenney
2012-02-21 1:11 ` Lai Jiangshan
2012-02-21 1:50 ` Paul E. McKenney
2012-02-21 8:44 ` Lai Jiangshan
2012-02-21 17:24 ` Paul E. McKenney
2012-02-22 9:29 ` [PATCH 1/3 RFC paul/rcu/srcu] srcu: Remove fast check path Lai Jiangshan
2012-02-22 9:29 ` [PATCH 2/3 RFC paul/rcu/srcu] srcu: only increase the upper bit for srcu_read_lock() Lai Jiangshan
2012-02-22 9:50 ` Peter Zijlstra
2012-02-22 21:20 ` Paul E. McKenney
2012-02-22 21:26 ` Paul E. McKenney
2012-02-22 21:39 ` Steven Rostedt
2012-02-23 1:01 ` Paul E. McKenney
2012-02-22 9:29 ` [PATCH 3/3 RFC paul/rcu/srcu] srcu: flip only once for every grace period Lai Jiangshan
2012-02-23 1:01 ` Paul E. McKenney
2012-02-24 8:06 ` Lai Jiangshan
2012-02-24 20:01 ` Paul E. McKenney
2012-02-27 8:01 ` Lai Jiangshan [this message]
2012-02-27 8:01 ` [PATCH 2/2 RFC] srcu: implement Peter's checking algorithm Lai Jiangshan
2012-02-27 18:30 ` Paul E. McKenney
2012-02-28 1:51 ` Lai Jiangshan
2012-02-28 13:47 ` Paul E. McKenney
2012-02-29 10:07 ` Lai Jiangshan
2012-02-29 13:55 ` Paul E. McKenney
2012-03-01 2:31 ` Lai Jiangshan
2012-03-01 13:20 ` Paul E. McKenney
2012-03-10 3:41 ` Lai Jiangshan
2012-03-06 8:42 ` [RFC PATCH 0/6 paul/rcu/srcu] srcu: implement call_srcu() Lai Jiangshan
2012-03-06 9:57 ` [PATCH 1/6] remove unused srcu_barrier() Lai Jiangshan
2012-03-06 9:57 ` [PATCH 2/6] Don't touch the snap in srcu_readers_active() Lai Jiangshan
2012-03-08 19:14 ` Paul E. McKenney
2012-03-06 9:57 ` [PATCH 3/6] use "int trycount" instead of "bool expedited" Lai Jiangshan
2012-03-08 19:25 ` Paul E. McKenney
2012-03-06 9:57 ` [PATCH 4/6] remove flip_idx_and_wait() Lai Jiangshan
2012-03-06 10:41 ` Peter Zijlstra
2012-03-07 3:54 ` [RFC PATCH 5/5 single-thread-version] implement per-domain single-thread state machine call_srcu() Lai Jiangshan
2012-03-08 13:04 ` Peter Zijlstra
2012-03-08 14:17 ` Lai Jiangshan
2012-03-08 13:08 ` Peter Zijlstra
2012-03-08 20:35 ` Paul E. McKenney
2012-03-10 3:16 ` Lai Jiangshan
2012-03-12 18:03 ` Paul E. McKenney
2012-03-14 7:47 ` Lai Jiangshan
2012-04-10 20:15 ` Paul E. McKenney
2012-03-06 9:57 ` [RFC PATCH 5/6] implement per-cpu&per-domain " Lai Jiangshan
2012-03-06 10:47 ` Peter Zijlstra
2012-03-08 19:44 ` Paul E. McKenney
2012-03-06 10:58 ` Peter Zijlstra
2012-03-06 15:17 ` Lai Jiangshan
2012-03-06 15:38 ` Peter Zijlstra
2012-03-08 19:49 ` Paul E. McKenney
2012-03-10 10:12 ` Peter Zijlstra
2012-03-12 17:52 ` Paul E. McKenney
2012-03-06 11:16 ` Peter Zijlstra
2012-03-06 15:12 ` Lai Jiangshan
2012-03-06 15:34 ` Peter Zijlstra
2012-03-08 19:58 ` Paul E. McKenney
2012-03-10 3:32 ` Lai Jiangshan
2012-03-10 10:09 ` Peter Zijlstra
2012-03-12 17:54 ` Paul E. McKenney
2012-03-12 17:58 ` Peter Zijlstra
2012-03-12 18:32 ` Paul E. McKenney
2012-03-12 20:25 ` Peter Zijlstra
2012-03-12 23:15 ` Paul E. McKenney
2012-03-12 23:18 ` Peter Zijlstra
2012-03-12 23:38 ` Paul E. McKenney
2012-03-06 15:26 ` Lai Jiangshan
2012-03-06 15:37 ` Peter Zijlstra
2012-03-06 11:17 ` Peter Zijlstra
2012-03-06 11:22 ` Peter Zijlstra
2012-03-06 11:35 ` Peter Zijlstra
2012-03-06 11:36 ` Peter Zijlstra
2012-03-06 11:39 ` Peter Zijlstra
2012-03-06 14:50 ` Lai Jiangshan
2012-03-06 11:52 ` Peter Zijlstra
2012-03-06 14:44 ` Lai Jiangshan
2012-03-06 15:31 ` Peter Zijlstra
2012-03-06 15:32 ` Peter Zijlstra
2012-03-07 6:44 ` Lai Jiangshan
2012-03-07 8:10 ` Gilad Ben-Yossef
2012-03-07 9:21 ` Lai Jiangshan
2012-03-06 14:47 ` Lai Jiangshan
2012-03-06 9:57 ` [PATCH 6/6] add srcu torture test Lai Jiangshan
2012-03-08 19:03 ` [PATCH 1/6] remove unused srcu_barrier() Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F4B383C.1000804@cn.fujitsu.com \
--to=laijs@cn.fujitsu.com \
--cc=Valdis.Kletnieks@vt.edu \
--cc=akpm@linux-foundation.org \
--cc=darren@dvhart.com \
--cc=dhowells@redhat.com \
--cc=dipankar@in.ibm.com \
--cc=eric.dumazet@gmail.com \
--cc=fweisbec@gmail.com \
--cc=josh@joshtriplett.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@polymtl.ca \
--cc=mingo@elte.hu \
--cc=niv@us.ibm.com \
--cc=patches@linaro.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.