From: "Paul E. McKenney" <paulmck@linux.ibm.com>
To: Joel Fernandes <joel@joelfernandes.org>
Cc: rcu@vger.kernel.org
Subject: Re: need_heavy_qs flag for PREEMPT=y kernels
Date: Thu, 15 Aug 2019 10:17:14 -0700 [thread overview]
Message-ID: <20190815171714.GA1023@linux.ibm.com> (raw)
In-Reply-To: <20190813010249.GA129011@google.com>
On Mon, Aug 12, 2019 at 09:02:49PM -0400, Joel Fernandes wrote:
> On Mon, Aug 12, 2019 at 04:01:38PM -0700, Paul E. McKenney wrote:
[ . . . ]
> > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > index 8c494a692728..ad906d6a74fb 100644
> > --- a/kernel/rcu/tree.c
> > +++ b/kernel/rcu/tree.c
> > @@ -651,6 +651,12 @@ static __always_inline void rcu_nmi_exit_common(bool irq)
> > */
> > if (rdp->dynticks_nmi_nesting != 1) {
> > trace_rcu_dyntick(TPS("--="), rdp->dynticks_nmi_nesting, rdp->dynticks_nmi_nesting - 2, rdp->dynticks);
> > + if (tick_nohz_full_cpu(rdp->cpu) &&
> > + rdp->dynticks_nmi_nesting == 2 &&
> > + rdp->rcu_urgent_qs && !rdp->rcu_forced_tick) {
> > + rdp->rcu_forced_tick = true;
> > + tick_dep_set_cpu(rdp->cpu, TICK_DEP_MASK_RCU);
> > + }
>
>
> Instead of checking dynticks_nmi_nesting == 2 in rcu_nmi_exit_common(), can
> we do the tick_dep_set_cpu(rdp->cpu, TICK_DEP_MASK_RCU) from
> rcu_nmi_enter_common() ? We could add this code there, under the "if
> (rcu_dynticks_curr_cpu_in_eqs())".
This would need to go in an "else" clause, correct? But there would still
want to be a check for interrupt from base level (which would admittedly
be an equality comparison with zero) and we would also still need to check
for rdp->rcu_urgent_qs && !rdp->rcu_forced_tick.
Still, an equal-zero comparison is probably going to be a bit cheaper than
an equals-two comparison, and this is on the interrupt-entry fastpath,
so this change is likely worth making. Good call!!!
Thanx, Paul
> I will test this patch tomorrow and let you know how it goes.
>
> thanks,
>
> - Joel
>
>
>
>
> > WRITE_ONCE(rdp->dynticks_nmi_nesting, /* No store tearing. */
> > rdp->dynticks_nmi_nesting - 2);
> > return;
> > @@ -886,6 +892,16 @@ void rcu_irq_enter_irqson(void)
> > local_irq_restore(flags);
> > }
> >
> > +/*
> > + * If the scheduler-clock interrupt was enabled on a nohz_full CPU
> > + * in order to get to a quiescent state, disable it.
> > + */
> > +void rcu_disable_tick_upon_qs(struct rcu_data *rdp)
> > +{
> > + if (tick_nohz_full_cpu(rdp->cpu) && rdp->rcu_forced_tick)
> > + tick_dep_clear_cpu(rdp->cpu, TICK_DEP_MASK_RCU);
> > +}
> > +
> > /**
> > * rcu_is_watching - see if RCU thinks that the current CPU is not idle
> > *
> > @@ -1980,6 +1996,7 @@ rcu_report_qs_rdp(int cpu, struct rcu_data *rdp)
> > if (!offloaded)
> > needwake = rcu_accelerate_cbs(rnp, rdp);
> >
> > + rcu_disable_tick_upon_qs(rdp);
> > rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags);
> > /* ^^^ Released rnp->lock */
> > if (needwake)
> > @@ -2269,6 +2286,7 @@ static void force_qs_rnp(int (*f)(struct rcu_data *rdp))
> > int cpu;
> > unsigned long flags;
> > unsigned long mask;
> > + struct rcu_data *rdp;
> > struct rcu_node *rnp;
> >
> > rcu_for_each_leaf_node(rnp) {
> > @@ -2293,8 +2311,10 @@ static void force_qs_rnp(int (*f)(struct rcu_data *rdp))
> > for_each_leaf_node_possible_cpu(rnp, cpu) {
> > unsigned long bit = leaf_node_cpu_bit(rnp, cpu);
> > if ((rnp->qsmask & bit) != 0) {
> > - if (f(per_cpu_ptr(&rcu_data, cpu)))
> > - mask |= bit;
> > + rdp = per_cpu_ptr(&rcu_data, cpu);
> > + if (f(rdp))
> > + rcu_disable_tick_upon_qs(rdp);
> > + mask |= bit;
> > }
> > }
> > if (mask != 0) {
> > @@ -2322,7 +2342,7 @@ void rcu_force_quiescent_state(void)
> > rnp = __this_cpu_read(rcu_data.mynode);
> > for (; rnp != NULL; rnp = rnp->parent) {
> > ret = (READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_FQS) ||
> > - !raw_spin_trylock(&rnp->fqslock);
> > + !raw_spin_trylock(&rnp->fqslock);
> > if (rnp_old != NULL)
> > raw_spin_unlock(&rnp_old->fqslock);
> > if (ret)
> > @@ -2855,7 +2875,7 @@ static void rcu_barrier_callback(struct rcu_head *rhp)
> > {
> > if (atomic_dec_and_test(&rcu_state.barrier_cpu_count)) {
> > rcu_barrier_trace(TPS("LastCB"), -1,
> > - rcu_state.barrier_sequence);
> > + rcu_state.barrier_sequence);
> > complete(&rcu_state.barrier_completion);
> > } else {
> > rcu_barrier_trace(TPS("CB"), -1, rcu_state.barrier_sequence);
> > @@ -2879,7 +2899,7 @@ static void rcu_barrier_func(void *unused)
> > } else {
> > debug_rcu_head_unqueue(&rdp->barrier_head);
> > rcu_barrier_trace(TPS("IRQNQ"), -1,
> > - rcu_state.barrier_sequence);
> > + rcu_state.barrier_sequence);
> > }
> > rcu_nocb_unlock(rdp);
> > }
> > @@ -2906,7 +2926,7 @@ void rcu_barrier(void)
> > /* Did someone else do our work for us? */
> > if (rcu_seq_done(&rcu_state.barrier_sequence, s)) {
> > rcu_barrier_trace(TPS("EarlyExit"), -1,
> > - rcu_state.barrier_sequence);
> > + rcu_state.barrier_sequence);
> > smp_mb(); /* caller's subsequent code after above check. */
> > mutex_unlock(&rcu_state.barrier_mutex);
> > return;
> > @@ -2938,11 +2958,11 @@ void rcu_barrier(void)
> > continue;
> > if (rcu_segcblist_n_cbs(&rdp->cblist)) {
> > rcu_barrier_trace(TPS("OnlineQ"), cpu,
> > - rcu_state.barrier_sequence);
> > + rcu_state.barrier_sequence);
> > smp_call_function_single(cpu, rcu_barrier_func, NULL, 1);
> > } else {
> > rcu_barrier_trace(TPS("OnlineNQ"), cpu,
> > - rcu_state.barrier_sequence);
> > + rcu_state.barrier_sequence);
> > }
> > }
> > put_online_cpus();
> > @@ -3168,6 +3188,7 @@ void rcu_cpu_starting(unsigned int cpu)
> > rdp->rcu_onl_gp_seq = READ_ONCE(rcu_state.gp_seq);
> > rdp->rcu_onl_gp_flags = READ_ONCE(rcu_state.gp_flags);
> > if (rnp->qsmask & mask) { /* RCU waiting on incoming CPU? */
> > + rcu_disable_tick_upon_qs(rdp);
> > /* Report QS -after- changing ->qsmaskinitnext! */
> > rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags);
> > } else {
> > diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
> > index c612f306fe89..055c31781d3a 100644
> > --- a/kernel/rcu/tree.h
> > +++ b/kernel/rcu/tree.h
> > @@ -181,6 +181,7 @@ struct rcu_data {
> > atomic_t dynticks; /* Even value for idle, else odd. */
> > bool rcu_need_heavy_qs; /* GP old, so heavy quiescent state! */
> > bool rcu_urgent_qs; /* GP old need light quiescent state. */
> > + bool rcu_forced_tick; /* Forced tick to provide QS. */
> > #ifdef CONFIG_RCU_FAST_NO_HZ
> > bool all_lazy; /* All CPU's CBs lazy at idle start? */
> > unsigned long last_accelerate; /* Last jiffy CBs were accelerated. */
next prev parent reply other threads:[~2019-08-15 17:17 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-11 18:08 need_heavy_qs flag for PREEMPT=y kernels Joel Fernandes
2019-08-11 18:34 ` Joel Fernandes
2019-08-11 21:16 ` Paul E. McKenney
2019-08-11 21:25 ` Joel Fernandes
2019-08-11 23:30 ` Paul E. McKenney
2019-08-12 1:24 ` Joel Fernandes
2019-08-12 1:40 ` Joel Fernandes
2019-08-12 3:57 ` Paul E. McKenney
2019-08-11 21:13 ` Paul E. McKenney
2019-08-12 3:21 ` Joel Fernandes
2019-08-12 3:53 ` Paul E. McKenney
2019-08-12 21:20 ` Joel Fernandes
2019-08-12 23:01 ` Paul E. McKenney
2019-08-13 1:02 ` Joel Fernandes
2019-08-13 1:05 ` Joel Fernandes
2019-08-13 2:28 ` Paul E. McKenney
2019-08-13 2:27 ` Paul E. McKenney
2019-08-13 2:50 ` Paul E. McKenney
2019-08-15 17:17 ` Paul E. McKenney [this message]
2019-08-15 20:04 ` Joel Fernandes
2019-08-15 20:31 ` Paul E. McKenney
2019-08-15 21:22 ` Joel Fernandes
2019-08-15 21:27 ` Joel Fernandes
2019-08-15 21:34 ` Joel Fernandes
2019-08-15 21:57 ` Paul E. McKenney
2019-08-15 21:45 ` Paul E. McKenney
2019-08-16 0:02 ` Joel Fernandes
2019-08-19 12:34 ` Frederic Weisbecker
2019-08-19 12:09 ` Frederic Weisbecker
2019-08-19 16:57 ` Frederic Weisbecker
2019-08-19 22:31 ` 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=20190815171714.GA1023@linux.ibm.com \
--to=paulmck@linux.ibm.com \
--cc=joel@joelfernandes.org \
--cc=rcu@vger.kernel.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.