All of lore.kernel.org
 help / color / mirror / Atom feed
* [RELEASE] Userspace RCU 0.3.0
@ 2009-11-03 15:02 Mathieu Desnoyers
  2009-11-03 15:50 ` Paul E. McKenney
  0 siblings, 1 reply; 4+ messages in thread
From: Mathieu Desnoyers @ 2009-11-03 15:02 UTC (permalink / raw)
  To: Josh Triplett, Jon Bernard, Jan Blunck, Paul E. McKenney,
	Pierre Habouzit, Steven Munroe, Bert Wesarg,
	Pierre-Marc Fournier
  Cc: ltt-dev, rp, linux-kernel

Hi everyone,

I released userspace RCU 0.3.0, which includes a small API change for
the "deferred work" interface. After discussion with Paul, I decided to
drop the support for call_rcu() and only provide defer_rcu(), to make
sure I don't provide an API with the same name as the kernel RCU but
with different arguments and semantic. It will generate the following
linker error if used:

file.c:240: undefined reference to 
   `__error_call_rcu_not_implemented_please_use_defer_rcu'

Note that defer_rcu() should *not* be used in RCU read-side C.S.,
because it calls synchronize_rcu() if the queue is full. This is a major
distinction from call_rcu(). (note to self: eventually we should add
some self-check code to detect defer_rcu() nested within RCU read-side
C.S.).

I plan to eventually implement a proper call_rcu() within the userspace
RCU library. It's not, however, a short-term need for me at the moment.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RELEASE] Userspace RCU 0.3.0
  2009-11-03 15:02 [RELEASE] Userspace RCU 0.3.0 Mathieu Desnoyers
@ 2009-11-03 15:50 ` Paul E. McKenney
  2009-11-03 16:53   ` Mathieu Desnoyers
  0 siblings, 1 reply; 4+ messages in thread
From: Paul E. McKenney @ 2009-11-03 15:50 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Josh Triplett, Jon Bernard, Jan Blunck, Pierre Habouzit,
	Steven Munroe, Bert Wesarg, Pierre-Marc Fournier, ltt-dev, rp,
	linux-kernel

On Tue, Nov 03, 2009 at 10:02:34AM -0500, Mathieu Desnoyers wrote:
> Hi everyone,
> 
> I released userspace RCU 0.3.0, which includes a small API change for
> the "deferred work" interface. After discussion with Paul, I decided to
> drop the support for call_rcu() and only provide defer_rcu(), to make
> sure I don't provide an API with the same name as the kernel RCU but
> with different arguments and semantic. It will generate the following
> linker error if used:
> 
> file.c:240: undefined reference to 
>    `__error_call_rcu_not_implemented_please_use_defer_rcu'
> 
> Note that defer_rcu() should *not* be used in RCU read-side C.S.,
> because it calls synchronize_rcu() if the queue is full. This is a major
> distinction from call_rcu(). (note to self: eventually we should add
> some self-check code to detect defer_rcu() nested within RCU read-side
> C.S.).
> 
> I plan to eventually implement a proper call_rcu() within the userspace
> RCU library. It's not, however, a short-term need for me at the moment.

I can tell that we need to get you going on some real-time work.  ;-)

(Sorry, but I really couldn't resist!)

							Thanx, Paul

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RELEASE] Userspace RCU 0.3.0
  2009-11-03 15:50 ` Paul E. McKenney
@ 2009-11-03 16:53   ` Mathieu Desnoyers
  2009-11-04  6:23     ` Paul E. McKenney
  0 siblings, 1 reply; 4+ messages in thread
From: Mathieu Desnoyers @ 2009-11-03 16:53 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Josh Triplett, Jon Bernard, Jan Blunck, Pierre Habouzit,
	Steven Munroe, Bert Wesarg, Pierre-Marc Fournier, ltt-dev, rp,
	linux-kernel

* Paul E. McKenney (paulmck@linux.vnet.ibm.com) wrote:
> On Tue, Nov 03, 2009 at 10:02:34AM -0500, Mathieu Desnoyers wrote:
> > Hi everyone,
> > 
> > I released userspace RCU 0.3.0, which includes a small API change for
> > the "deferred work" interface. After discussion with Paul, I decided to
> > drop the support for call_rcu() and only provide defer_rcu(), to make
> > sure I don't provide an API with the same name as the kernel RCU but
> > with different arguments and semantic. It will generate the following
> > linker error if used:
> > 
> > file.c:240: undefined reference to 
> >    `__error_call_rcu_not_implemented_please_use_defer_rcu'
> > 
> > Note that defer_rcu() should *not* be used in RCU read-side C.S.,
> > because it calls synchronize_rcu() if the queue is full. This is a major
> > distinction from call_rcu(). (note to self: eventually we should add
> > some self-check code to detect defer_rcu() nested within RCU read-side
> > C.S.).
> > 
> > I plan to eventually implement a proper call_rcu() within the userspace
> > RCU library. It's not, however, a short-term need for me at the moment.
> 
> I can tell that we need to get you going on some real-time work.  ;-)
> 

:-)

> (Sorry, but I really couldn't resist!)
> 

It's true that it becomes important when real-time behavior is required
at the call_rcu() execution site. However, even typical use of
call_rcu() has some limitations in this area: in a scenario where the
struct rcu_head passed to call_rcu() is allocated dynamically, kmalloc
and friends do not offer any kind of wait-free/lock-free guarantees. So
the way call_rcu() works is to push the burden of RT impact on the
original struct rcu_head allocation. But I agree that it makes
out-of-memory/queue full error handling much easier, because all the
allocation is done at the same site.

The main disadvantage of the call_rcu() approach though is that I cannot
see any clean way to perform call_rcu() rate-limitation on a per-cpu
basis. This would basically imply that we have to stop providing RT
call_rcu() at some point to ensure we do not go over a certain
threshold.

A possible solution would be to make call_rcu() return an error when it
goes over some threshold. The caller would have to deal with the error,
possibly by rejecting the whole operation (so maybe another CPU/cloud
node could take over the work). This seems cleaner than delaying
execution of the call_rcu() site. The caller could actually decide to
either reject the whole operation or to delay its execution.

Mathieu


> 							Thanx, Paul

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RELEASE] Userspace RCU 0.3.0
  2009-11-03 16:53   ` Mathieu Desnoyers
@ 2009-11-04  6:23     ` Paul E. McKenney
  0 siblings, 0 replies; 4+ messages in thread
From: Paul E. McKenney @ 2009-11-04  6:23 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Josh Triplett, Jon Bernard, Jan Blunck, Pierre Habouzit,
	Steven Munroe, Bert Wesarg, Pierre-Marc Fournier, ltt-dev, rp,
	linux-kernel

On Tue, Nov 03, 2009 at 11:53:14AM -0500, Mathieu Desnoyers wrote:
> * Paul E. McKenney (paulmck@linux.vnet.ibm.com) wrote:
> > On Tue, Nov 03, 2009 at 10:02:34AM -0500, Mathieu Desnoyers wrote:
> > > Hi everyone,
> > > 
> > > I released userspace RCU 0.3.0, which includes a small API change for
> > > the "deferred work" interface. After discussion with Paul, I decided to
> > > drop the support for call_rcu() and only provide defer_rcu(), to make
> > > sure I don't provide an API with the same name as the kernel RCU but
> > > with different arguments and semantic. It will generate the following
> > > linker error if used:
> > > 
> > > file.c:240: undefined reference to 
> > >    `__error_call_rcu_not_implemented_please_use_defer_rcu'
> > > 
> > > Note that defer_rcu() should *not* be used in RCU read-side C.S.,
> > > because it calls synchronize_rcu() if the queue is full. This is a major
> > > distinction from call_rcu(). (note to self: eventually we should add
> > > some self-check code to detect defer_rcu() nested within RCU read-side
> > > C.S.).
> > > 
> > > I plan to eventually implement a proper call_rcu() within the userspace
> > > RCU library. It's not, however, a short-term need for me at the moment.
> > 
> > I can tell that we need to get you going on some real-time work.  ;-)
> 
> :-)
> 
> > (Sorry, but I really couldn't resist!)
> 
> It's true that it becomes important when real-time behavior is required
> at the call_rcu() execution site. However, even typical use of
> call_rcu() has some limitations in this area: in a scenario where the
> struct rcu_head passed to call_rcu() is allocated dynamically, kmalloc
> and friends do not offer any kind of wait-free/lock-free guarantees. So
> the way call_rcu() works is to push the burden of RT impact on the
> original struct rcu_head allocation. But I agree that it makes
> out-of-memory/queue full error handling much easier, because all the
> allocation is done at the same site.
> 
> The main disadvantage of the call_rcu() approach though is that I cannot
> see any clean way to perform call_rcu() rate-limitation on a per-cpu
> basis. This would basically imply that we have to stop providing RT
> call_rcu() at some point to ensure we do not go over a certain
> threshold.

Or that we use other means to accelerate the grace period when any given
CPU starts getting filled up, such as force_quiescent_state().  Now,
force_quiescent_state() is not exactly lightweight, but at that point,
we should not be all that concerned about incurring some extra overhead.

Now, an RCU read-side critical section might take forever, but then
you are stuck no matter what you do.  And this is why SRCU has a
separate API that does not include a call_srcu().

> A possible solution would be to make call_rcu() return an error when it
> goes over some threshold. The caller would have to deal with the error,
> possibly by rejecting the whole operation (so maybe another CPU/cloud
> node could take over the work). This seems cleaner than delaying
> execution of the call_rcu() site. The caller could actually decide to
> either reject the whole operation or to delay its execution.

That sort of error handling usually turns out to be surprisingly
complex, difficult to test, and prone to bugs.  Having a deterministic
call_rcu() that avoids error returns is actually quite valuable.

The problem in user mode is that you cannot guarantee that a given
thread won't get preempted for an extended time period.  One approach
would be to make call_rcu() provide a conditional guarantee, so
that it (for example) provides deterministic execution time only
if readers are getting done in a timely manner and if the call_rcu()
rate is bounded.  But even that would prohibit call_rcu() from being
invoked from within an RCU read-side critical section.

So another approach is to test whether call_rcu() is being invoked
from within an RCU read-side critical section, and only block if
not.  And yet a another would be for call_rcu() to block for a fixed
time period if within an RCU read-side critical section.  Either way,
the system would make forward progress if at least -some- of the
call_rcu() invocations were from outside of RCU read-side critical
sections.

							Thanx, Paul

> Mathieu
> 
> 
> > 							Thanx, Paul
> 
> -- 
> Mathieu Desnoyers
> OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-11-04  6:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-03 15:02 [RELEASE] Userspace RCU 0.3.0 Mathieu Desnoyers
2009-11-03 15:50 ` Paul E. McKenney
2009-11-03 16:53   ` Mathieu Desnoyers
2009-11-04  6:23     ` Paul E. McKenney

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.