public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	linux-kernel@vger.kernel.org,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Mike Galbraith <efault@gmx.de>, Paul Mackerras <paulus@samba.org>,
	Stephane Eranian <eranian@google.com>,
	Andi Kleen <ak@linux.intel.com>
Subject: Re: [PATCH] [RFC] perf: Fix a race between ring_buffer_detach() and ring_buffer_wakeup()
Date: Mon, 17 Mar 2014 12:18:07 +0100	[thread overview]
Message-ID: <20140317111807.GE27965@twins.programming.kicks-ass.net> (raw)
In-Reply-To: <20140315000009.GA28008@linux.vnet.ibm.com>

> rcu: Provide grace-period piggybacking API
>     
> The following pattern is currently not well supported by RCU:
>     
> 1.	Make data element inaccessible to RCU readers.
>     
> 2.	Do work that probably lasts for more than one grace period.
>     
> 3.	Do something to make sure RCU readers in flight before #1 above
>     	have completed.
>     
> Here are some things that could currently be done:
>     
> a.	Do a synchronize_rcu() unconditionally at either #1 or #3 above.
>     	This works, but imposes needless work and latency.
>     
> b.	Post an RCU callback at #1 above that does a wakeup, then
>     	wait for the wakeup at #3.  This works well, but likely results
>     	in an extra unneeded grace period.  Open-coding this is also
>     	a bit more semi-tricky code than would be good.
> 
> This commit therefore adds get_state_synchronize_rcu() and
> cond_synchronize_rcu() APIs.  Call get_state_synchronize_rcu() at #1
> above and pass its return value to cond_synchronize_rcu() at #3 above.
> This results in a call to synchronize_rcu() if no grace period has
> elapsed between #1 and #3, but requires only a load, comparison, and
> memory barrier if a full grace period did elapse.
> 
> Reported-by: Peter Zijlstra <peterz@infradead.org>

More a requested-by, I'd say.

> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> +/**
> + * get_state_synchronize_rcu - Snapshot current RCU state
> + *
> + * Returns a cookie that is used by a later call to cond_synchronize_rcu()
> + * to determine whether or not a full grace period has elapsed in the
> + * meantime.
> + */
> +unsigned long get_state_synchronize_rcu(void)
> +{

/*
 * Make sure this load happens before anything following it; such that
 * ... ?
 */

The way I imaged using this is taking this snapshot after the RCU
operation, such that we err towards seeing a later grace period and
synchronizing too much in stead of seeing an earlier and sync'ing too
little.

Such use would suggest the barrier the other way around.

> +	return smp_load_acquire(&rcu_state->gpnum);
> +}
> +EXPORT_SYMBOL_GPL(get_state_synchronize_rcu);

I can't say I'm excited about that function name; but I'm also
completely lacking in alternatives.

> +
> +/**
> + * cond_synchronize_rcu - Conditionally wait for an RCU grace period
> + *
> + * @oldstate: return value from earlier call to get_state_synchronize_rcu()
> + *
> + * If a full RCU grace period has elapsed since the earlier call to
> + * get_state_synchronize_rcu(), just return.  Otherwise, invoke
> + * synchronize_rcu() to wait for a full grace period.
> + */
> +void cond_synchronize_rcu(unsigned long oldstate)
> +{
> +	unsigned long newstate = smp_load_acquire(&rcu_state->completed);

Again, uncommented barriers; the load_acquire seems to suggest you want
to make sure the sync_rcu() bits happen after this read. But seeing how
sync_rcu() will invariably read the same data again and you get an
address dep this seems somewhat superfluous.

Then again, can't hurt I suppose :-)

> +	if (ULONG_CMP_GE(oldstate, newstate))

So if the observed active gp (oldstate) is ahead or equal to the last
completed gp, then we wait?

I thought the double grace period thing was for preemptible rcu; is it
done here because you don't want to special case the preemptible rcu and
make do with a single implementation?

And I suppose that on wrap around; we do extra sync_rcu() calls, which
can never be wrong.

> +		synchronize_rcu();
> +}
> +EXPORT_SYMBOL_GPL(cond_synchronize_rcu);


  reply	other threads:[~2014-03-17 11:18 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-07 13:38 [PATCH] [RFC] perf: Fix a race between ring_buffer_detach() and ring_buffer_wakeup() Alexander Shishkin
2014-03-13 19:58 ` Paul E. McKenney
2014-03-14  9:50   ` Peter Zijlstra
2014-03-14 20:47     ` Paul E. McKenney
2014-03-14 22:43       ` Peter Zijlstra
2014-03-14 23:02         ` Paul E. McKenney
2014-03-15  0:00           ` Paul E. McKenney
2014-03-17 11:18             ` Peter Zijlstra [this message]
2014-03-17 16:48               ` Paul E. McKenney
2014-03-17 17:30                 ` Peter Zijlstra
2014-03-18  2:45                   ` Paul E. McKenney
2014-03-18  8:26                     ` Peter Zijlstra
2014-05-07 12:35     ` Peter Zijlstra
2014-05-07 18:06       ` Peter Zijlstra
2014-05-08 15:37         ` Paul E. McKenney
2014-05-08 16:09           ` Peter Zijlstra
2014-05-19 12:48       ` [tip:perf/urgent] perf: Fix a race between ring_buffer_detach() and ring_buffer_attach() tip-bot for Peter Zijlstra

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=20140317111807.GE27965@twins.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=efault@gmx.de \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=paulus@samba.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox