On Fri, Jul 06, 2012 at 02:00:14PM +0200, Frederic Weisbecker wrote: > Allow calls to rcu_user_enter() even if we are already > in userspace (as seen by RCU) and allow calls to rcu_user_exit() > even if we are already in the kernel. > > This makes the APIs more flexible to be called from architectures. > Exception entries for example won't need to know if they come from > userspace before calling rcu_user_exit().
You lost me on this one. As long as the nesting level stays below a few tens, rcu_user_enter() and rcu_user_exit() already can nest. Or are you saying that you need to deal with duplicate rcu_user_enter() calls that must be matched by a single rcu_user_exit() call? Thanx, Paul > Signed-off-by: Frederic Weisbecker <fweis...@gmail.com> > Cc: Alessio Igor Bogani <abog...@kernel.org> > Cc: Andrew Morton <a...@linux-foundation.org> > Cc: Avi Kivity <a...@redhat.com> > Cc: Chris Metcalf <cmetc...@tilera.com> > Cc: Christoph Lameter <c...@linux.com> > Cc: Geoff Levand <ge...@infradead.org> > Cc: Gilad Ben Yossef <gi...@benyossef.com> > Cc: Hakan Akkan <hakanak...@gmail.com> > Cc: H. Peter Anvin <h...@zytor.com> > Cc: Ingo Molnar <mi...@kernel.org> > Cc: Josh Triplett <j...@joshtriplett.org> > Cc: Kevin Hilman <khil...@ti.com> > Cc: Max Krasnyansky <m...@qualcomm.com> > Cc: Peter Zijlstra <pet...@infradead.org> > Cc: Stephen Hemminger <shemmin...@vyatta.com> > Cc: Steven Rostedt <rost...@goodmis.org> > Cc: Sven-Thorsten Dietrich <thebigcorporat...@gmail.com> > Cc: Thomas Gleixner <t...@linutronix.de> > --- > kernel/rcutree.c | 38 ++++++++++++++++++++++++++++++-------- > 1 files changed, 30 insertions(+), 8 deletions(-) > > diff --git a/kernel/rcutree.c b/kernel/rcutree.c > index 64fc2cd..81a86ec 100644 > --- a/kernel/rcutree.c > +++ b/kernel/rcutree.c > @@ -344,6 +344,10 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp) > return 0; > } > > +#ifdef CONFIG_RCU_USER_QS > +static DEFINE_PER_CPU(bool, in_user); > +#endif > + > /* > * rcu_eqs_enter_common - current CPU is moving towards extended quiescent > state > * > @@ -389,11 +393,9 @@ static void rcu_eqs_enter_common(struct rcu_dynticks > *rdtp, long long oldval, > */ > static void rcu_eqs_enter(bool user) > { > - unsigned long flags; > long long oldval; > struct rcu_dynticks *rdtp; > > - local_irq_save(flags); > rdtp = &__get_cpu_var(rcu_dynticks); > oldval = rdtp->dynticks_nesting; > WARN_ON_ONCE((oldval & DYNTICK_TASK_NEST_MASK) == 0); > @@ -402,7 +404,6 @@ static void rcu_eqs_enter(bool user) > else > rdtp->dynticks_nesting -= DYNTICK_TASK_NEST_VALUE; > rcu_eqs_enter_common(rdtp, oldval, user); > - local_irq_restore(flags); > } > > /** > @@ -419,7 +420,11 @@ static void rcu_eqs_enter(bool user) > */ > void rcu_idle_enter(void) > { > + unsigned long flags; > + > + local_irq_save(flags); > rcu_eqs_enter(0); > + local_irq_restore(flags); > } > EXPORT_SYMBOL_GPL(rcu_idle_enter); > > @@ -434,7 +439,16 @@ EXPORT_SYMBOL_GPL(rcu_idle_enter); > */ > void rcu_user_enter(void) > { > - rcu_eqs_enter(1); > + unsigned long flags; > + > + WARN_ON_ONCE(!current->mm); > + > + local_irq_save(flags); > + if (!this_cpu_read(in_user)) { > + this_cpu_write(in_user, true); > + rcu_eqs_enter(1); > + } > + local_irq_restore(flags); > } > EXPORT_SYMBOL_GPL(rcu_user_enter); > #endif > @@ -530,11 +544,9 @@ static void rcu_eqs_exit_common(struct rcu_dynticks > *rdtp, long long oldval, > */ > static void rcu_eqs_exit(bool user) > { > - unsigned long flags; > struct rcu_dynticks *rdtp; > long long oldval; > > - local_irq_save(flags); > rdtp = &__get_cpu_var(rcu_dynticks); > oldval = rdtp->dynticks_nesting; > WARN_ON_ONCE(oldval < 0); > @@ -543,7 +555,6 @@ static void rcu_eqs_exit(bool user) > else > rdtp->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE; > rcu_eqs_exit_common(rdtp, oldval, user); > - local_irq_restore(flags); > } > > /** > @@ -559,7 +570,11 @@ static void rcu_eqs_exit(bool user) > */ > void rcu_idle_exit(void) > { > + unsigned long flags; > + > + local_irq_save(flags); > rcu_eqs_exit(0); > + local_irq_restore(flags); > } > EXPORT_SYMBOL_GPL(rcu_idle_exit); > > @@ -572,7 +587,14 @@ EXPORT_SYMBOL_GPL(rcu_idle_exit); > */ > void rcu_user_exit(void) > { > - rcu_eqs_exit(1); > + unsigned long flags; > + > + local_irq_save(flags); > + if (this_cpu_read(in_user)) { > + this_cpu_write(in_user, false); > + rcu_eqs_exit(1); > + } > + local_irq_restore(flags); > } > EXPORT_SYMBOL_GPL(rcu_user_exit); > #endif > -- > 1.7.5.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/