From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Lai Jiangshan <laijs@cn.fujitsu.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: Re: [PATCH 3/3 RFC paul/rcu/srcu] srcu: flip only once for every grace period
Date: Wed, 22 Feb 2012 17:01:00 -0800 [thread overview]
Message-ID: <20120223010100.GP2416@linux.vnet.ibm.com> (raw)
In-Reply-To: <4F44B580.6040003@cn.fujitsu.com>
On Wed, Feb 22, 2012 at 05:29:36PM +0800, Lai Jiangshan wrote:
> >From 4ddf62aaf2c4ebe6b9d4a1c596e8b43a678f1f0d Mon Sep 17 00:00:00 2001
> From: Lai Jiangshan <laijs@cn.fujitsu.com>
> Date: Wed, 22 Feb 2012 14:12:02 +0800
> Subject: [PATCH 3/3 RFC paul/rcu/srcu] srcu: flip only once for every grace period
>
> flip_idx_and_wait() is not changed, and is split as two functions
> and only a short comments is added for smp_mb() E.
>
> __synchronize_srcu() use a different algorithm for "leak" readers.
> detail is in the comments of the patch.
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
And I queued this one as well, with some adjustment to the comments.
These are now available at:
git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/srcu
Assuming testing goes well, these might go into 3.4.
Thanx, Paul
> ---
> kernel/srcu.c | 105 ++++++++++++++++++++++++++++++++++----------------------
> 1 files changed, 64 insertions(+), 41 deletions(-)
>
> diff --git a/kernel/srcu.c b/kernel/srcu.c
> index a51ac48..346f9d7 100644
> --- a/kernel/srcu.c
> +++ b/kernel/srcu.c
> @@ -249,6 +249,37 @@ EXPORT_SYMBOL_GPL(__srcu_read_unlock);
> */
> #define SYNCHRONIZE_SRCU_READER_DELAY 5
>
> +static void wait_idx(struct srcu_struct *sp, int idx, bool expedited)
> +{
> + int trycount = 0;
> +
> + /*
> + * SRCU read-side critical sections are normally short, so wait
> + * a small amount of time before possibly blocking.
> + */
> + if (!srcu_readers_active_idx_check(sp, idx)) {
> + udelay(SYNCHRONIZE_SRCU_READER_DELAY);
> + while (!srcu_readers_active_idx_check(sp, idx)) {
> + if (expedited && ++ trycount < 10)
> + udelay(SYNCHRONIZE_SRCU_READER_DELAY);
> + else
> + schedule_timeout_interruptible(1);
> + }
> + }
> +
> + /*
> + * The following smp_mb() E pairs with srcu_read_unlock()'s
> + * smp_mb C to ensure that if srcu_readers_active_idx_check()
> + * sees srcu_read_unlock()'s counter decrement, then any
> + * of the current task's subsequent code will happen after
> + * that SRCU read-side critical section.
> + *
> + * It also ensures the order between the above waiting and
> + * the next flipping.
> + */
> + smp_mb(); /* E */
> +}
> +
> /*
> * Flip the readers' index by incrementing ->completed, then wait
> * until there are no more readers using the counters referenced by
> @@ -258,12 +289,12 @@ EXPORT_SYMBOL_GPL(__srcu_read_unlock);
> * 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 __synchronize_srcu() invoking flip_idx_and_wait() twice.
> + * by the next __synchronize_srcu() invoking wait_idx() for such readers
> + * before start a new grace perioad.
> */
> static void flip_idx_and_wait(struct srcu_struct *sp, bool expedited)
> {
> int idx;
> - int trycount = 0;
>
> idx = sp->completed++ & 0x1;
>
> @@ -278,28 +309,7 @@ static void flip_idx_and_wait(struct srcu_struct *sp, bool expedited)
> */
> smp_mb(); /* D */
>
> - /*
> - * SRCU read-side critical sections are normally short, so wait
> - * a small amount of time before possibly blocking.
> - */
> - if (!srcu_readers_active_idx_check(sp, idx)) {
> - udelay(SYNCHRONIZE_SRCU_READER_DELAY);
> - while (!srcu_readers_active_idx_check(sp, idx)) {
> - if (expedited && ++ trycount < 10)
> - udelay(SYNCHRONIZE_SRCU_READER_DELAY);
> - else
> - schedule_timeout_interruptible(1);
> - }
> - }
> -
> - /*
> - * The following smp_mb() E pairs with srcu_read_unlock()'s
> - * smp_mb C to ensure that if srcu_readers_active_idx_check()
> - * sees srcu_read_unlock()'s counter decrement, then any
> - * of the current task's subsequent code will happen after
> - * that SRCU read-side critical section.
> - */
> - smp_mb(); /* E */
> + wait_idx(sp, idx, expedited);
> }
>
> /*
> @@ -307,8 +317,6 @@ static void flip_idx_and_wait(struct srcu_struct *sp, bool expedited)
> */
> static void __synchronize_srcu(struct srcu_struct *sp, bool expedited)
> {
> - int idx = 0;
> -
> rcu_lockdep_assert(!lock_is_held(&sp->dep_map) &&
> !lock_is_held(&rcu_bh_lock_map) &&
> !lock_is_held(&rcu_lock_map) &&
> @@ -318,27 +326,42 @@ static void __synchronize_srcu(struct srcu_struct *sp, bool expedited)
> mutex_lock(&sp->mutex);
>
> /*
> - * If there were no helpers, then we need to do two flips of
> - * the index. The first flip is required if there are any
> - * outstanding SRCU readers even if there are no new readers
> - * running concurrently with the first counter flip.
> - *
> - * The second flip is required when a new reader picks up
> + * When in the previous grace perioad, if a reader picks up
> * the old value of the index, but does not increment its
> * counter until after its counters is summed/rechecked by
> - * srcu_readers_active_idx_check(). In this case, the current SRCU
> + * srcu_readers_active_idx_check(). In this case, the previous SRCU
> * grace period would be OK because the SRCU read-side critical
> - * section started after this SRCU grace period started, so the
> + * section started after the SRCU grace period started, so the
> * grace period is not required to wait for the reader.
> *
> - * However, the next SRCU grace period would be waiting for the
> - * other set of counters to go to zero, and therefore would not
> - * wait for the reader, which would be very bad. To avoid this
> - * bad scenario, we flip and wait twice, clearing out both sets
> - * of counters.
> + * However, such leftover readers affect this new SRCU grace period.
> + * So we have to wait for such readers. This wait_idx() should be
> + * considerred as the wait_idx() in the flip_idx_and_wait() of
> + * the previous grace perioad except that it is for leftover readers
> + * started before this synchronize_srcu(). So when it returns,
> + * there is no leftover readers that starts before this grace period.
> + *
> + * If there are some leftover readers that do not increment its
> + * counter until after its counters is summed/rechecked by
> + * srcu_readers_active_idx_check(), In this case, this SRCU
> + * grace period would be OK as above comments says. We defines
> + * such readers as leftover-leftover readers, we consider these
> + * readers fteched index of (sp->completed + 1), it means they
> + * are considerred as exactly the same as the readers after this
> + * grace period.
> + *
> + * wait_idx() is expected very fast, because leftover readers
> + * are unlikely produced.
> */
> - for (; idx < 2; idx++)
> - flip_idx_and_wait(sp, expedited);
> + wait_idx(sp, (sp->completed - 1) & 0x1, expedited);
> +
> + /*
> + * Starts a new grace period, this flip is required if there are
> + * any outstanding SRCU readers even if there are no new readers
> + * running concurrently with the counter flip.
> + */
> + flip_idx_and_wait(sp, expedited);
> +
> mutex_unlock(&sp->mutex);
> }
>
> --
> 1.7.4.4
>
next prev parent reply other threads:[~2012-02-23 1:01 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 [this message]
2012-02-24 8:06 ` Lai Jiangshan
2012-02-24 20:01 ` Paul E. McKenney
2012-02-27 8:01 ` [PATCH 1/2 RFC] srcu: change the comments of the wait algorithm Lai Jiangshan
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=20120223010100.GP2416@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.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=laijs@cn.fujitsu.com \
--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=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.