rcu: Create and use an rcu_rdp_cpu_online()
authorPaul E. McKenney <paulmck@kernel.org>
Fri, 10 Dec 2021 21:44:17 +0000 (13:44 -0800)
committerPaul E. McKenney <paulmck@kernel.org>
Tue, 8 Feb 2022 18:12:28 +0000 (10:12 -0800)
The pattern "rdp->grpmask & rcu_rnp_online_cpus(rnp)" occurs frequently
in RCU code in order to determine whether rdp->cpu is online from an
RCU perspective.  This commit therefore creates an rcu_rdp_cpu_online()
function to replace it.

[ paulmck: Apply kernel test robot unused-variable feedback. ]

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
kernel/rcu/tree.c
kernel/rcu/tree_plugin.h

index 2d70b91..1d3507d 100644 (file)
@@ -222,6 +222,16 @@ static unsigned long rcu_rnp_online_cpus(struct rcu_node *rnp)
        return READ_ONCE(rnp->qsmaskinitnext);
 }
 
+/*
+ * Is the CPU corresponding to the specified rcu_data structure online
+ * from RCU's perspective?  This perspective is given by that structure's
+ * ->qsmaskinitnext field rather than by the global cpu_online_mask.
+ */
+static bool rcu_rdp_cpu_online(struct rcu_data *rdp)
+{
+       return !!(rdp->grpmask & rcu_rnp_online_cpus(rdp->mynode));
+}
+
 /*
  * Return true if an RCU grace period is in progress.  The READ_ONCE()s
  * permit this function to be invoked without holding the root rcu_node
@@ -1168,14 +1178,12 @@ void rcu_request_urgent_qs_task(struct task_struct *t)
 bool rcu_lockdep_current_cpu_online(void)
 {
        struct rcu_data *rdp;
-       struct rcu_node *rnp;
        bool ret = false;
 
        if (in_nmi() || !rcu_scheduler_fully_active)
                return true;
        preempt_disable_notrace();
        rdp = this_cpu_ptr(&rcu_data);
-       rnp = rdp->mynode;
        /*
         * Strictly, we care here about the case where the current CPU is
         * in rcu_cpu_starting() and thus has an excuse for rdp->grpmask
@@ -1183,8 +1191,7 @@ bool rcu_lockdep_current_cpu_online(void)
         * false positive if it's held by some *other* CPU, but that's
         * OK because that just means a false *negative* on the warning.
         */
-       if (rdp->grpmask & rcu_rnp_online_cpus(rnp) ||
-           arch_spin_is_locked(&rcu_state.ofl_lock))
+       if (rcu_rdp_cpu_online(rdp) || arch_spin_is_locked(&rcu_state.ofl_lock))
                ret = true;
        preempt_enable_notrace();
        return ret;
@@ -1269,8 +1276,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
         * For more detail, please refer to the "Hotplug CPU" section
         * of RCU's Requirements documentation.
         */
-       if (WARN_ON_ONCE(!(rdp->grpmask & rcu_rnp_online_cpus(rnp)))) {
-               bool onl;
+       if (WARN_ON_ONCE(!rcu_rdp_cpu_online(rdp))) {
                struct rcu_node *rnp1;
 
                pr_info("%s: grp: %d-%d level: %d ->gp_seq %ld ->completedqs %ld\n",
@@ -1279,9 +1285,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
                for (rnp1 = rnp; rnp1; rnp1 = rnp1->parent)
                        pr_info("%s: %d:%d ->qsmask %#lx ->qsmaskinit %#lx ->qsmaskinitnext %#lx ->rcu_gp_init_mask %#lx\n",
                                __func__, rnp1->grplo, rnp1->grphi, rnp1->qsmask, rnp1->qsmaskinit, rnp1->qsmaskinitnext, rnp1->rcu_gp_init_mask);
-               onl = !!(rdp->grpmask & rcu_rnp_online_cpus(rnp));
                pr_info("%s %d: %c online: %ld(%d) offline: %ld(%d)\n",
-                       __func__, rdp->cpu, ".o"[onl],
+                       __func__, rdp->cpu, ".o"[rcu_rdp_cpu_online(rdp)],
                        (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_flags,
                        (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_flags);
                return 1; /* Break things loose after complaining. */
index c5b45c2..d3db216 100644 (file)
@@ -330,7 +330,7 @@ void rcu_note_context_switch(bool preempt)
                 * then queue the task as required based on the states
                 * of any ongoing and expedited grace periods.
                 */
-               WARN_ON_ONCE((rdp->grpmask & rcu_rnp_online_cpus(rnp)) == 0);
+               WARN_ON_ONCE(!rcu_rdp_cpu_online(rdp));
                WARN_ON_ONCE(!list_empty(&t->rcu_node_entry));
                trace_rcu_preempt_task(rcu_state.name,
                                       t->pid,
@@ -773,7 +773,6 @@ dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
        int cpu;
        int i;
        struct list_head *lhp;
-       bool onl;
        struct rcu_data *rdp;
        struct rcu_node *rnp1;
 
@@ -797,9 +796,8 @@ dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
        pr_cont("\n");
        for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++) {
                rdp = per_cpu_ptr(&rcu_data, cpu);
-               onl = !!(rdp->grpmask & rcu_rnp_online_cpus(rnp));
                pr_info("\t%d: %c online: %ld(%d) offline: %ld(%d)\n",
-                       cpu, ".o"[onl],
+                       cpu, ".o"[rcu_rdp_cpu_online(rdp)],
                        (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_flags,
                        (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_flags);
        }