Re: [PATCH tip/core/rcu 22/30] rcu: Don't flag non-starting GPs before GP kthread is running

From: Steven Rostedt
Date: Mon Feb 17 2020 - 15:25:22 EST


On Sat, 15 Feb 2020 05:42:08 -0800
"Paul E. McKenney" <paulmck@xxxxxxxxxx> wrote:

>
> And does the following V2 look better?
>

For the issue I brought up, yes. But now I have to ask...

> @@ -1252,10 +1253,10 @@ static bool rcu_future_gp_cleanup(struct rcu_node *rnp)
> */
> static void rcu_gp_kthread_wake(void)
> {
> - if ((current == rcu_state.gp_kthread &&
> - !in_irq() && !in_serving_softirq()) ||
> - !READ_ONCE(rcu_state.gp_flags) ||
> - !rcu_state.gp_kthread)
> + struct task_struct *t = READ_ONCE(rcu_state.gp_kthread);
> +
> + if ((current == t && !in_irq() && !in_serving_softirq()) ||
> + !READ_ONCE(rcu_state.gp_flags) || !t)

Why not test !t first? As that is the fastest operation in the if
statement, and will shortcut all the other operations if it is true.

As I like to micro-optimize ;-), for or (||) statements, I like to add
the fastest operations first. To me, that would be:

if (!t || READ_ONCE(rcu_state.gp_flags) ||
(current == t && !in_irq() && !in_serving_softirq()))
return;

Note, in_irq() reads preempt_count which is not always a fast operation.

-- Steve


> return;
> WRITE_ONCE(rcu_state.gp_wake_time, jiffies);
> WRITE_ONCE(rcu_state.gp_wake_seq, READ_ONCE(rcu_state.gp_seq));
> @@ -3554,7 +3555,10 @@ static int __init rcu_spawn_gp_kthread(void)
> }
> rnp = rcu_get_root();
> raw_spin_lock_irqsave_rcu_node(rnp, flags);
> - rcu_state.gp_kthread = t;
> + WRITE_ONCE(rcu_state.gp_activity, jiffies);
> + WRITE_ONCE(rcu_state.gp_req_activity, jiffies);
> + // Reset .gp_activity and .gp_req_activity before setting .gp_kthread.
> + smp_store_release(&rcu_state.gp_kthread, t); /* ^^^ */
> raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
> wake_up_process(t);
> rcu_spawn_nocb_kthreads();
> diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h
> index 488b71d..16ad7ad 100644
\