aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/tree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-08-17 20:05:59 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-10-09 17:25:17 -0400
commit9b9500da81502738efa1b485a8835f174ff7be6d (patch)
treea768a5aecca5e268ca4a90e9a312f87c729d4438 /kernel/rcu/tree.c
parentf79c3ad6189624c3de0ad5521610c9e22a1c33cf (diff)
rcu: Make RCU CPU stall warnings check for irq-disabled CPUs
One common question upon seeing an RCU CPU stall warning is "did the stalled CPUs have interrupts disabled?" However, the current stall warnings are silent on this point. This commit therefore uses irq_work to check whether stalled CPUs still respond to IPIs, and flags this state in the RCU CPU stall warning console messages. Reported-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r--kernel/rcu/tree.c104
1 files changed, 92 insertions, 12 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 0dda57a28276..12838a9a128e 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1207,6 +1207,22 @@ static int rcu_is_cpu_rrupt_from_idle(void)
1207} 1207}
1208 1208
1209/* 1209/*
1210 * We are reporting a quiescent state on behalf of some other CPU, so
1211 * it is our responsibility to check for and handle potential overflow
1212 * of the rcu_node ->gpnum counter with respect to the rcu_data counters.
1213 * After all, the CPU might be in deep idle state, and thus executing no
1214 * code whatsoever.
1215 */
1216static void rcu_gpnum_ovf(struct rcu_node *rnp, struct rcu_data *rdp)
1217{
1218 lockdep_assert_held(&rnp->lock);
1219 if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4, rnp->gpnum))
1220 WRITE_ONCE(rdp->gpwrap, true);
1221 if (ULONG_CMP_LT(rdp->rcu_iw_gpnum + ULONG_MAX / 4, rnp->gpnum))
1222 rdp->rcu_iw_gpnum = rnp->gpnum + ULONG_MAX / 4;
1223}
1224
1225/*
1210 * Snapshot the specified CPU's dynticks counter so that we can later 1226 * Snapshot the specified CPU's dynticks counter so that we can later
1211 * credit them with an implicit quiescent state. Return 1 if this CPU 1227 * credit them with an implicit quiescent state. Return 1 if this CPU
1212 * is in dynticks idle mode, which is an extended quiescent state. 1228 * is in dynticks idle mode, which is an extended quiescent state.
@@ -1216,15 +1232,34 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp)
1216 rdp->dynticks_snap = rcu_dynticks_snap(rdp->dynticks); 1232 rdp->dynticks_snap = rcu_dynticks_snap(rdp->dynticks);
1217 if (rcu_dynticks_in_eqs(rdp->dynticks_snap)) { 1233 if (rcu_dynticks_in_eqs(rdp->dynticks_snap)) {
1218 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti")); 1234 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
1219 if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4, 1235 rcu_gpnum_ovf(rdp->mynode, rdp);
1220 rdp->mynode->gpnum))
1221 WRITE_ONCE(rdp->gpwrap, true);
1222 return 1; 1236 return 1;
1223 } 1237 }
1224 return 0; 1238 return 0;
1225} 1239}
1226 1240
1227/* 1241/*
1242 * Handler for the irq_work request posted when a grace period has
1243 * gone on for too long, but not yet long enough for an RCU CPU
1244 * stall warning. Set state appropriately, but just complain if
1245 * there is unexpected state on entry.
1246 */
1247static void rcu_iw_handler(struct irq_work *iwp)
1248{
1249 struct rcu_data *rdp;
1250 struct rcu_node *rnp;
1251
1252 rdp = container_of(iwp, struct rcu_data, rcu_iw);
1253 rnp = rdp->mynode;
1254 raw_spin_lock_rcu_node(rnp);
1255 if (!WARN_ON_ONCE(!rdp->rcu_iw_pending)) {
1256 rdp->rcu_iw_gpnum = rnp->gpnum;
1257 rdp->rcu_iw_pending = false;
1258 }
1259 raw_spin_unlock_rcu_node(rnp);
1260}
1261
1262/*
1228 * Return true if the specified CPU has passed through a quiescent 1263 * Return true if the specified CPU has passed through a quiescent
1229 * state by virtue of being in or having passed through an dynticks 1264 * state by virtue of being in or having passed through an dynticks
1230 * idle state since the last call to dyntick_save_progress_counter() 1265 * idle state since the last call to dyntick_save_progress_counter()
@@ -1235,7 +1270,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
1235 unsigned long jtsq; 1270 unsigned long jtsq;
1236 bool *rnhqp; 1271 bool *rnhqp;
1237 bool *ruqp; 1272 bool *ruqp;
1238 struct rcu_node *rnp; 1273 struct rcu_node *rnp = rdp->mynode;
1239 1274
1240 /* 1275 /*
1241 * If the CPU passed through or entered a dynticks idle phase with 1276 * If the CPU passed through or entered a dynticks idle phase with
@@ -1248,6 +1283,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
1248 if (rcu_dynticks_in_eqs_since(rdp->dynticks, rdp->dynticks_snap)) { 1283 if (rcu_dynticks_in_eqs_since(rdp->dynticks, rdp->dynticks_snap)) {
1249 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti")); 1284 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
1250 rdp->dynticks_fqs++; 1285 rdp->dynticks_fqs++;
1286 rcu_gpnum_ovf(rnp, rdp);
1251 return 1; 1287 return 1;
1252 } 1288 }
1253 1289
@@ -1258,12 +1294,12 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
1258 * might not be the case for nohz_full CPUs looping in the kernel. 1294 * might not be the case for nohz_full CPUs looping in the kernel.
1259 */ 1295 */
1260 jtsq = jiffies_till_sched_qs; 1296 jtsq = jiffies_till_sched_qs;
1261 rnp = rdp->mynode;
1262 ruqp = per_cpu_ptr(&rcu_dynticks.rcu_urgent_qs, rdp->cpu); 1297 ruqp = per_cpu_ptr(&rcu_dynticks.rcu_urgent_qs, rdp->cpu);
1263 if (time_after(jiffies, rdp->rsp->gp_start + jtsq) && 1298 if (time_after(jiffies, rdp->rsp->gp_start + jtsq) &&
1264 READ_ONCE(rdp->rcu_qs_ctr_snap) != per_cpu(rcu_dynticks.rcu_qs_ctr, rdp->cpu) && 1299 READ_ONCE(rdp->rcu_qs_ctr_snap) != per_cpu(rcu_dynticks.rcu_qs_ctr, rdp->cpu) &&
1265 READ_ONCE(rdp->gpnum) == rnp->gpnum && !rdp->gpwrap) { 1300 READ_ONCE(rdp->gpnum) == rnp->gpnum && !rdp->gpwrap) {
1266 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("rqc")); 1301 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("rqc"));
1302 rcu_gpnum_ovf(rnp, rdp);
1267 return 1; 1303 return 1;
1268 } else if (time_after(jiffies, rdp->rsp->gp_start + jtsq)) { 1304 } else if (time_after(jiffies, rdp->rsp->gp_start + jtsq)) {
1269 /* Load rcu_qs_ctr before store to rcu_urgent_qs. */ 1305 /* Load rcu_qs_ctr before store to rcu_urgent_qs. */
@@ -1274,6 +1310,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
1274 if (!(rdp->grpmask & rcu_rnp_online_cpus(rnp))) { 1310 if (!(rdp->grpmask & rcu_rnp_online_cpus(rnp))) {
1275 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl")); 1311 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl"));
1276 rdp->offline_fqs++; 1312 rdp->offline_fqs++;
1313 rcu_gpnum_ovf(rnp, rdp);
1277 return 1; 1314 return 1;
1278 } 1315 }
1279 1316
@@ -1305,11 +1342,22 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
1305 } 1342 }
1306 1343
1307 /* 1344 /*
1308 * If more than halfway to RCU CPU stall-warning time, do 1345 * If more than halfway to RCU CPU stall-warning time, do a
1309 * a resched_cpu() to try to loosen things up a bit. 1346 * resched_cpu() to try to loosen things up a bit. Also check to
1347 * see if the CPU is getting hammered with interrupts, but only
1348 * once per grace period, just to keep the IPIs down to a dull roar.
1310 */ 1349 */
1311 if (jiffies - rdp->rsp->gp_start > rcu_jiffies_till_stall_check() / 2) 1350 if (jiffies - rdp->rsp->gp_start > rcu_jiffies_till_stall_check() / 2) {
1312 resched_cpu(rdp->cpu); 1351 resched_cpu(rdp->cpu);
1352 if (IS_ENABLED(CONFIG_IRQ_WORK) &&
1353 !rdp->rcu_iw_pending && rdp->rcu_iw_gpnum != rnp->gpnum &&
1354 (rnp->ffmask & rdp->grpmask)) {
1355 init_irq_work(&rdp->rcu_iw, rcu_iw_handler);
1356 rdp->rcu_iw_pending = true;
1357 rdp->rcu_iw_gpnum = rnp->gpnum;
1358 irq_work_queue_on(&rdp->rcu_iw, rdp->cpu);
1359 }
1360 }
1313 1361
1314 return 0; 1362 return 0;
1315} 1363}
@@ -1498,6 +1546,7 @@ static void print_cpu_stall(struct rcu_state *rsp)
1498{ 1546{
1499 int cpu; 1547 int cpu;
1500 unsigned long flags; 1548 unsigned long flags;
1549 struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
1501 struct rcu_node *rnp = rcu_get_root(rsp); 1550 struct rcu_node *rnp = rcu_get_root(rsp);
1502 long totqlen = 0; 1551 long totqlen = 0;
1503 1552
@@ -1513,7 +1562,9 @@ static void print_cpu_stall(struct rcu_state *rsp)
1513 */ 1562 */
1514 pr_err("INFO: %s self-detected stall on CPU", rsp->name); 1563 pr_err("INFO: %s self-detected stall on CPU", rsp->name);
1515 print_cpu_stall_info_begin(); 1564 print_cpu_stall_info_begin();
1565 raw_spin_lock_irqsave_rcu_node(rdp->mynode, flags);
1516 print_cpu_stall_info(rsp, smp_processor_id()); 1566 print_cpu_stall_info(rsp, smp_processor_id());
1567 raw_spin_unlock_irqrestore_rcu_node(rdp->mynode, flags);
1517 print_cpu_stall_info_end(); 1568 print_cpu_stall_info_end();
1518 for_each_possible_cpu(cpu) 1569 for_each_possible_cpu(cpu)
1519 totqlen += rcu_segcblist_n_cbs(&per_cpu_ptr(rsp->rda, 1570 totqlen += rcu_segcblist_n_cbs(&per_cpu_ptr(rsp->rda,
@@ -1907,6 +1958,7 @@ static bool __note_gp_changes(struct rcu_state *rsp, struct rcu_node *rnp,
1907 rdp->core_needs_qs = need_gp; 1958 rdp->core_needs_qs = need_gp;
1908 zero_cpu_stall_ticks(rdp); 1959 zero_cpu_stall_ticks(rdp);
1909 WRITE_ONCE(rdp->gpwrap, false); 1960 WRITE_ONCE(rdp->gpwrap, false);
1961 rcu_gpnum_ovf(rnp, rdp);
1910 } 1962 }
1911 return ret; 1963 return ret;
1912} 1964}
@@ -3685,6 +3737,8 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
3685 rdp->cpu_no_qs.b.norm = true; 3737 rdp->cpu_no_qs.b.norm = true;
3686 rdp->rcu_qs_ctr_snap = per_cpu(rcu_dynticks.rcu_qs_ctr, cpu); 3738 rdp->rcu_qs_ctr_snap = per_cpu(rcu_dynticks.rcu_qs_ctr, cpu);
3687 rdp->core_needs_qs = false; 3739 rdp->core_needs_qs = false;
3740 rdp->rcu_iw_pending = false;
3741 rdp->rcu_iw_gpnum = rnp->gpnum - 1;
3688 trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuonl")); 3742 trace_rcu_grace_period(rsp->name, rdp->gpnum, TPS("cpuonl"));
3689 raw_spin_unlock_irqrestore_rcu_node(rnp, flags); 3743 raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
3690} 3744}
@@ -3722,10 +3776,24 @@ static void rcutree_affinity_setting(unsigned int cpu, int outgoing)
3722 */ 3776 */
3723int rcutree_online_cpu(unsigned int cpu) 3777int rcutree_online_cpu(unsigned int cpu)
3724{ 3778{
3725 sync_sched_exp_online_cleanup(cpu); 3779 unsigned long flags;
3726 rcutree_affinity_setting(cpu, -1); 3780 struct rcu_data *rdp;
3781 struct rcu_node *rnp;
3782 struct rcu_state *rsp;
3783
3784 for_each_rcu_flavor(rsp) {
3785 rdp = per_cpu_ptr(rsp->rda, cpu);
3786 rnp = rdp->mynode;
3787 raw_spin_lock_irqsave_rcu_node(rnp, flags);
3788 rnp->ffmask |= rdp->grpmask;
3789 raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
3790 }
3727 if (IS_ENABLED(CONFIG_TREE_SRCU)) 3791 if (IS_ENABLED(CONFIG_TREE_SRCU))
3728 srcu_online_cpu(cpu); 3792 srcu_online_cpu(cpu);
3793 if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE)
3794 return 0; /* Too early in boot for scheduler work. */
3795 sync_sched_exp_online_cleanup(cpu);
3796 rcutree_affinity_setting(cpu, -1);
3729 return 0; 3797 return 0;
3730} 3798}
3731 3799
@@ -3735,6 +3803,19 @@ int rcutree_online_cpu(unsigned int cpu)
3735 */ 3803 */
3736int rcutree_offline_cpu(unsigned int cpu) 3804int rcutree_offline_cpu(unsigned int cpu)
3737{ 3805{
3806 unsigned long flags;
3807 struct rcu_data *rdp;
3808 struct rcu_node *rnp;
3809 struct rcu_state *rsp;
3810
3811 for_each_rcu_flavor(rsp) {
3812 rdp = per_cpu_ptr(rsp->rda, cpu);
3813 rnp = rdp->mynode;
3814 raw_spin_lock_irqsave_rcu_node(rnp, flags);
3815 rnp->ffmask &= ~rdp->grpmask;
3816 raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
3817 }
3818
3738 rcutree_affinity_setting(cpu, cpu); 3819 rcutree_affinity_setting(cpu, cpu);
3739 if (IS_ENABLED(CONFIG_TREE_SRCU)) 3820 if (IS_ENABLED(CONFIG_TREE_SRCU))
3740 srcu_offline_cpu(cpu); 3821 srcu_offline_cpu(cpu);
@@ -4183,8 +4264,7 @@ void __init rcu_init(void)
4183 for_each_online_cpu(cpu) { 4264 for_each_online_cpu(cpu) {
4184 rcutree_prepare_cpu(cpu); 4265 rcutree_prepare_cpu(cpu);
4185 rcu_cpu_starting(cpu); 4266 rcu_cpu_starting(cpu);
4186 if (IS_ENABLED(CONFIG_TREE_SRCU)) 4267 rcutree_online_cpu(cpu);
4187 srcu_online_cpu(cpu);
4188 } 4268 }
4189} 4269}
4190 4270