aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/tree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2018-05-15 19:23:23 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2018-07-12 18:39:10 -0400
commitf2e2df59786d7bd52e6e7e2d10c1c6ba433a0ee7 (patch)
tree83228ad0b1384cdb37e5be871f21f9d1cbababc8 /kernel/rcu/tree.c
parentfea3f222d3523dfdd0e86b11227d3cda20765102 (diff)
rcu: Add diagnostics for offline CPUs failing to report QS
CPUs are expected to report quiescent states when coming online and when going offline, and grace-period initialization is supposed to handle any race conditions where a CPU's ->qsmask bit is set just after it goes offline. This commit adds diagnostics for the case where an offline CPU nevertheless has a grace period waiting on it. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r--kernel/rcu/tree.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index ee218d743226..d3333ee2c6f5 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1188,6 +1188,27 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
1188 smp_store_release(ruqp, true); 1188 smp_store_release(ruqp, true);
1189 } 1189 }
1190 1190
1191 /* If waiting too long on an offline CPU, complain. */
1192 if (!(rdp->grpmask & rcu_rnp_online_cpus(rnp)) &&
1193 time_after(jiffies, rdp->rsp->gp_start + HZ)) {
1194 bool onl;
1195 struct rcu_node *rnp1;
1196
1197 WARN_ON(1); /* Offline CPUs are supposed to report QS! */
1198 pr_info("%s: grp: %d-%d level: %d ->gp_seq %ld ->completedqs %ld\n",
1199 __func__, rnp->grplo, rnp->grphi, rnp->level,
1200 (long)rnp->gp_seq, (long)rnp->completedqs);
1201 for (rnp1 = rnp; rnp1; rnp1 = rnp1->parent)
1202 pr_info("%s: %d:%d ->qsmask %#lx ->qsmaskinit %#lx ->qsmaskinitnext %#lx ->rcu_gp_init_mask %#lx\n",
1203 __func__, rnp1->grplo, rnp1->grphi, rnp1->qsmask, rnp1->qsmaskinit, rnp1->qsmaskinitnext, rnp1->rcu_gp_init_mask);
1204 onl = !!(rdp->grpmask & rcu_rnp_online_cpus(rnp));
1205 pr_info("%s %d: %c online: %ld(%d) offline: %ld(%d)\n",
1206 __func__, rdp->cpu, ".o"[onl],
1207 (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_flags,
1208 (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_flags);
1209 return 1; /* Break things loose after complaining. */
1210 }
1211
1191 /* 1212 /*
1192 * A CPU running for an extended time within the kernel can 1213 * A CPU running for an extended time within the kernel can
1193 * delay RCU grace periods. When the CPU is in NO_HZ_FULL mode, 1214 * delay RCU grace periods. When the CPU is in NO_HZ_FULL mode,
@@ -1967,6 +1988,7 @@ static bool rcu_gp_init(struct rcu_state *rsp)
1967 rnp->grphi, rnp->qsmask); 1988 rnp->grphi, rnp->qsmask);
1968 /* Quiescent states for tasks on any now-offline CPUs. */ 1989 /* Quiescent states for tasks on any now-offline CPUs. */
1969 mask = rnp->qsmask & ~rnp->qsmaskinitnext; 1990 mask = rnp->qsmask & ~rnp->qsmaskinitnext;
1991 rnp->rcu_gp_init_mask = mask;
1970 if ((mask || rnp->wait_blkd_tasks) && rcu_is_leaf_node(rnp)) 1992 if ((mask || rnp->wait_blkd_tasks) && rcu_is_leaf_node(rnp))
1971 rcu_report_qs_rnp(mask, rsp, rnp, rnp->gp_seq, flags); 1993 rcu_report_qs_rnp(mask, rsp, rnp, rnp->gp_seq, flags);
1972 else 1994 else