From: Joel Fernandes <joel@joelfernandes.org>
To: "Paul E. McKenney" <paulmck@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Frederic Weisbecker <fweisbec@gmail.com>,
Jonathan Corbet <corbet@lwn.net>,
Josh Triplett <josh@joshtriplett.org>,
kernel-team@android.com, Lai Jiangshan <jiangshanlai@gmail.com>,
linux-doc@vger.kernel.org,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Mauro Carvalho Chehab <mchehab+samsung@kernel.org>,
rcu@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>
Subject: Re: [RFC v1 1/2] rcu/tree: Clean up dynticks counter usage
Date: Wed, 28 Aug 2019 17:56:57 -0400 [thread overview]
Message-ID: <20190828215657.GA71365@google.com> (raw)
In-Reply-To: <20190828201344.GR26530@linux.ibm.com>
On Wed, Aug 28, 2019 at 01:13:44PM -0700, Paul E. McKenney wrote:
> On Mon, Aug 26, 2019 at 09:33:53PM -0400, Joel Fernandes (Google) wrote:
> > The dynticks counter are confusing due to crowbar writes of
> > DYNTICK_IRQ_NONIDLE whose purpose is to detect half-interrupts (i.e. we
> > see rcu_irq_enter() but not rcu_irq_exit() due to a usermode upcall) and
> > if so then do a reset of the dyntick_nmi_nesting counters. This patch
> > tries to get rid of DYNTICK_IRQ_NONIDLE while still keeping the code
> > working, fully functional, and less confusing. The confusion recently
> > has even led to patches forgetting that DYNTICK_IRQ_NONIDLE was written
> > to which wasted lots of time.
> >
> > The patch has the following changes:
[snip]
> > /*
> > * Grace-period counter management.
> > */
> > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > index 68ebf0eb64c8..255cd6835526 100644
> > --- a/kernel/rcu/tree.c
> > +++ b/kernel/rcu/tree.c
> > @@ -81,7 +81,7 @@
> >
> > static DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, rcu_data) = {
> > .dynticks_nesting = 1,
> > - .dynticks_nmi_nesting = DYNTICK_IRQ_NONIDLE,
> > + .dynticks_nmi_nesting = 0,
>
> C initializes to zero by default, so this can simply be deleted.
Fixed.
> > .dynticks = ATOMIC_INIT(RCU_DYNTICK_CTRL_CTR),
> > };
> > struct rcu_state rcu_state = {
> > @@ -558,17 +558,18 @@ EXPORT_SYMBOL_GPL(rcutorture_get_gp_data);
> > /*
> > * Enter an RCU extended quiescent state, which can be either the
> > * idle loop or adaptive-tickless usermode execution.
> > - *
> > - * We crowbar the ->dynticks_nmi_nesting field to zero to allow for
> > - * the possibility of usermode upcalls having messed up our count
> > - * of interrupt nesting level during the prior busy period.
> > */
> > static void rcu_eqs_enter(bool user)
> > {
> > struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
> >
> > - WARN_ON_ONCE(rdp->dynticks_nmi_nesting != DYNTICK_IRQ_NONIDLE);
> > - WRITE_ONCE(rdp->dynticks_nmi_nesting, 0);
> > + /* Entering usermode/idle from interrupt is not handled. These would
> > + * mean usermode upcalls or idle entry happened from interrupts. But,
> > + * reset the counter if we warn.
> > + */
>
> Please either put the "/*" on its own line or use "//"-style comments.
I'll put "/*" on its own line.
> > WARN_ON_ONCE(rdp->dynticks_nmi_nesting <= 0);
> > WARN_ON_ONCE(rcu_dynticks_curr_cpu_in_eqs());
> >
> > + WRITE_ONCE(rdp->dynticks_nmi_nesting, /* No store tearing. */
> > + rdp->dynticks_nmi_nesting - 1);
>
> This is problematic. The +/-1 and +/-2 dance is specifically for NMIs, so...
This counter is deleted in the following patch so I hope its Ok to leave it
here for this one. I just kept it split into different patch to make
testing/review/development easier.
> > if (irq)
> > rcu_prepare_for_idle();
> > @@ -723,10 +728,6 @@ void rcu_irq_exit_irqson(void)
> > /*
> > * Exit an RCU extended quiescent state, which can be either the
> > * idle loop or adaptive-tickless usermode execution.
> > - *
> > - * We crowbar the ->dynticks_nmi_nesting field to DYNTICK_IRQ_NONIDLE to
> > - * allow for the possibility of usermode upcalls messing up our count of
> > - * interrupt nesting level during the busy period that is just now starting.
> > */
> > static void rcu_eqs_exit(bool user)
> > {
> > @@ -747,8 +748,13 @@ static void rcu_eqs_exit(bool user)
> > trace_rcu_dyntick(TPS("End"), rdp->dynticks_nesting, 1, rdp->dynticks);
> > WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !user && !is_idle_task(current));
> > WRITE_ONCE(rdp->dynticks_nesting, 1);
> > - WARN_ON_ONCE(rdp->dynticks_nmi_nesting);
> > - WRITE_ONCE(rdp->dynticks_nmi_nesting, DYNTICK_IRQ_NONIDLE);
> > +
> > + /* Exiting usermode/idle from interrupt is not handled. These would
> > + * mean usermode upcalls or idle exit happened from interrupts. But,
> > + * reset the counter if we warn.
> > + */
> > + if (WARN_ON_ONCE(rdp->dynticks_nmi_nesting != 0))
> > + WRITE_ONCE(rdp->dynticks_nmi_nesting, 0);
>
> And here. Plus this is adding a test and branch in the common case.
> Given that the location being written to should be hot in the cache,
> it is not clear that this is a win.
The next patch removes the branch itself and just has the warning.
> > WARN_ON_ONCE(rdp->dynticks_nmi_nesting < 0);
> >
> > /*
> > @@ -826,16 +833,21 @@ static __always_inline void rcu_nmi_enter_common(bool irq)
> >
> > incby = 1;
> > } else if (tick_nohz_full_cpu(rdp->cpu) &&
> > - rdp->dynticks_nmi_nesting == DYNTICK_IRQ_NONIDLE &&
> > - rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) {
> > + !rdp->dynticks_nmi_nesting && rdp->rcu_urgent_qs &&
> > + !rdp->rcu_forced_tick) {
>
> OK. Though you should be able to save a line by pulling the
> "rdp->rcu_urgent_qs &&" onto the first line.
Fixed.
> > rdp->rcu_forced_tick = true;
> > tick_dep_set_cpu(rdp->cpu, TICK_DEP_BIT_RCU);
> > }
> > +
>
> Not clear that the added blank line is a win, here or below.
Fixed,
thanks!
- Joel
[snip]
prev parent reply other threads:[~2019-08-28 21:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-27 1:33 [RFC v1 1/2] rcu/tree: Clean up dynticks counter usage Joel Fernandes (Google)
2019-08-28 20:13 ` Paul E. McKenney
2019-08-28 21:56 ` Joel Fernandes [this message]
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=20190828215657.GA71365@google.com \
--to=joel@joelfernandes.org \
--cc=corbet@lwn.net \
--cc=fweisbec@gmail.com \
--cc=jiangshanlai@gmail.com \
--cc=josh@joshtriplett.org \
--cc=kernel-team@android.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mchehab+samsung@kernel.org \
--cc=paulmck@kernel.org \
--cc=rcu@vger.kernel.org \
--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.