All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Pranith Kumar <bobby.prani@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Lai Jiangshan <laijs@cn.fujitsu.com>,
	"open list:READ-COPY UPDATE..." <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 11/16] rcu: Check for spurious wakeup using return value
Date: Thu, 24 Jul 2014 11:12:23 -0700	[thread overview]
Message-ID: <20140724181223.GO11241@linux.vnet.ibm.com> (raw)
In-Reply-To: <CAJhHMCDhwnKF5tiWvHyGrz3KhCab+QUnAfEmkzjsBrNn5O3gyQ@mail.gmail.com>

On Thu, Jul 24, 2014 at 12:03:34AM -0400, Pranith Kumar wrote:
> On Wed, Jul 23, 2014 at 11:43 PM, Paul E. McKenney
> <paulmck@linux.vnet.ibm.com> wrote:
> > On Wed, Jul 23, 2014 at 10:36:19PM -0400, Pranith Kumar wrote:
> >> On Wed, Jul 23, 2014 at 8:26 AM, Paul E. McKenney
> >> <paulmck@linux.vnet.ibm.com> wrote:
> >> > On Wed, Jul 23, 2014 at 01:09:48AM -0400, Pranith Kumar wrote:
> >> >> When the gp_kthread wakes up from the wait event, it returns 0 if the wake up is
> >> >> due to the condition having been met. This commit checks this return value
> >> >> for a spurious wake up before calling rcu_gp_init().
> >> >>
> >> >> Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
> >> >
> >> > How does this added check help?  I don't see that it does.  If the flag
> >> > is set, we want to wake up.  If we get a spurious wakeup, but then the
> >> > flag gets set before we actually wake up, we still want to wake up.
> >>
> >> So I took a look at the docs again, and using the return value is the
> >> recommended way to check for spurious wakeups.
> >>
> >> The condition in wait_event_interruptible() is checked when the task
> >> is woken up (either due to stray signals or explicitly) and it returns
> >> true if condition evaluates to true.
> 
> this should be returns '0' if the condition evaluates to true.

Ah, but if the condition changes while wait_event_interruptible() is in
the process of returning, it is quite possible that the answer will be
different afterwards.  For example, consider this scenario:

o	wait_event_interruptible() decides to return spuriously for
	whatever reason, and thus returns a non-zero value.

o	An invocation of (say) rcu_start_gp_advanced() sets ->gp_flags
	to RCU_GP_FLAG_INIT, thus requesting that a new grace period
	start.

o	At this point, the return value says that we should not start
	a new grace period, but the ->gp_flags value says that we
	should.

Because it is the ->gp_flags value that really knows, the current code
ignores wait_event_interruptible()'s return value and just checks
the ->gp_flags value.

> >> In the current scenario, if we get a spurious wakeup, we take the
> >> costly path of checking this condition again (with a barrier and lock)
> >> before going back to wait.
> >>
> >> The scenario of getting an actual wakeup after getting a spurious
> >> wakeup exists even today, this is the window after detecting a
> >> spurious wakeup and before going back to wait. I am not sure if using
> >> the return value enlarges that window as we are going back to sleep
> >> immediately.
> >>
> >> Thoughts?
> >
> > If the flag is set, why should we care whether or not the wakeup was
> > spurious?  If the flag is not set, why should we care whether or not
> > wait_event_interruptible() thought that the wakeup was not spurious?
> 
> A correction about the return value above: return will be 0 if the
> condition is true, in this case if the flag is set.
> 
> If the flag is set, ret will be 0 and we will go ahead with
> rcu_gp_init(). (no change wrt current behavior)

Sorry, this is not always correct.  RCU is highly concurrent, so you do
need to start thinking in terms of concurrency.  Your reasoning above
is a symptom of single-threaded thinking.  Please see my scenario above
showing how the return can be non-zero even though ->gp_flags is set.

> If the flag is not set, currently we go ahead and call rcu_gp_init()
> from where we check if the flag is set (after a lock+barrier) and
> return.

True enough.  Is that really a problem?  If so, exactly why is it a
problem?

> If we care about what wait_event_interruptible() returns, we can go
> back and wait for an actual wakeup much earlier without the additional
> overhead of calling rcu_gp_init().

The key phrase here is "If we care".  Should we care?  If so, why?

I suggest running some random benchmark and counting how many times
rcu_gp_init() is called and how many times rcu_gp_init() returns
because ->gp_flags is not set.  If rcu_gp_init() returns because
->gp_flags is not set a significant fraction of the time, then this
-might- be worth worrying about.  (Extra credit: Under what conditions
would it be worth worrying about, and how would you go about checking
to see whether those conditions hold?)

							Thanx, Paul


  reply	other threads:[~2014-07-24 18:12 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-23  5:09 [PATCH 00/16] rcu: Some minor fixes and cleanups Pranith Kumar
2014-07-23  5:09 ` [PATCH 01/16] rcu: Use rcu_num_nodes instead of NUM_RCU_NODES Pranith Kumar
2014-07-23  5:09 ` [PATCH 02/16] rcu: Check return value for cpumask allocation Pranith Kumar
2014-07-23 12:06   ` Paul E. McKenney
2014-07-23 12:49     ` Pranith Kumar
2014-07-23 17:14     ` Pranith Kumar
2014-07-23 18:01       ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 03/16] rcu: Fix comment for gp_state field values Pranith Kumar
2014-07-23  5:09 ` [PATCH 04/16] rcu: Remove redundant check for an online CPU Pranith Kumar
2014-07-23 12:09   ` Paul E. McKenney
2014-07-23 13:23     ` Pranith Kumar
2014-07-23 13:41       ` Paul E. McKenney
2014-07-23 14:01         ` Pranith Kumar
2014-07-23 14:14           ` Paul E. McKenney
2014-07-23 15:07             ` Pranith Kumar
2014-07-23 15:21               ` Pranith Kumar
2014-07-23  5:09 ` [PATCH 05/16] rcu: Add noreturn attribute to boost kthread Pranith Kumar
2014-07-23  5:09 ` [PATCH 06/16] rcu: Clear gp_flags only when actually starting new gp Pranith Kumar
2014-07-23 12:13   ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 07/16] rcu: Save and restore irq flags in rcu_gp_cleanup() Pranith Kumar
2014-07-23 12:16   ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 08/16] rcu: Clean up rcu_spawn_one_boost_kthread() Pranith Kumar
2014-07-23  5:09 ` [PATCH 09/16] rcu: Remove redundant check for online cpu Pranith Kumar
2014-07-23 12:21   ` Paul E. McKenney
2014-07-23 12:59     ` Pranith Kumar
2014-07-23 13:50       ` Paul E. McKenney
2014-07-23 14:12         ` Pranith Kumar
2014-07-23 14:23           ` Paul E. McKenney
2014-07-23 15:11             ` Pranith Kumar
2014-07-23 15:30               ` Paul E. McKenney
2014-07-23 15:44                 ` Pranith Kumar
2014-07-23 19:15                   ` Paul E. McKenney
2014-07-23 20:01                     ` Pranith Kumar
2014-07-23 20:16                     ` Pranith Kumar
2014-07-23 20:23                       ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 10/16] rcu: Check for RCU_FLAG_GP_INIT bit in gp_flags for spurious wakeup Pranith Kumar
2014-07-23 12:23   ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 11/16] rcu: Check for spurious wakeup using return value Pranith Kumar
2014-07-23 12:26   ` Paul E. McKenney
2014-07-24  2:36     ` Pranith Kumar
2014-07-24  3:43       ` Paul E. McKenney
2014-07-24  4:03         ` Pranith Kumar
2014-07-24 18:12           ` Paul E. McKenney [this message]
2014-07-24 19:59             ` Pranith Kumar
2014-07-24 20:27               ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 12/16] rcu: Rename rcu_spawn_gp_kthread() to rcu_spawn_kthreads() Pranith Kumar
2014-07-23  5:09 ` [PATCH 13/16] rcu: Spawn nocb kthreads from rcu_prepare_kthreads() Pranith Kumar
2014-07-23  5:09 ` [PATCH 14/16] rcu: Remove redundant checks for rcu_scheduler_fully_active Pranith Kumar
2014-07-23 12:27   ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 15/16] rcu: Check for a nocb cpu before trying to spawn nocb threads Pranith Kumar
2014-07-23 12:28   ` Paul E. McKenney
2014-07-23 13:14     ` Pranith Kumar
2014-07-23 13:42       ` Paul E. McKenney
2014-07-23  5:09 ` [PATCH 16/16] rcu: kvm.sh: Fix error when you pass --cpus argument Pranith Kumar
2014-07-23 12:31   ` Paul E. McKenney
2014-07-23 14:45 ` [PATCH 00/16] rcu: Some minor fixes and cleanups Paul E. McKenney
2014-08-27  1:10   ` Pranith Kumar
2014-08-27  3:20     ` 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=20140724181223.GO11241@linux.vnet.ibm.com \
    --to=paulmck@linux.vnet.ibm.com \
    --cc=bobby.prani@gmail.com \
    --cc=josh@joshtriplett.org \
    --cc=laijs@cn.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=rostedt@goodmis.org \
    /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.