Skip to content

Commit 8837582

Browse files
committed
rcu: When GP kthread is starved, tag idle threads as false positives
If the grace-period kthread is starved, idle threads' extended quiescent states are not reported. These idle threads thus wrongly appear to be blocking the current grace period. This commit therefore tags such idle threads as probable false positives when the grace-period kthread is being starved. Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 654db05 commit 8837582

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

kernel/rcu/tree_stall.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,16 @@ static const char *gp_state_getname(short gs)
299299
return gp_state_names[gs];
300300
}
301301

302+
/* Is the RCU grace-period kthread being starved of CPU time? */
303+
static bool rcu_is_gp_kthread_starving(unsigned long *jp)
304+
{
305+
unsigned long j = jiffies - READ_ONCE(rcu_state.gp_activity);
306+
307+
if (jp)
308+
*jp = j;
309+
return j > 2 * HZ;
310+
}
311+
302312
/*
303313
* Print out diagnostic information for the specified stalled CPU.
304314
*
@@ -313,6 +323,7 @@ static const char *gp_state_getname(short gs)
313323
static void print_cpu_stall_info(int cpu)
314324
{
315325
unsigned long delta;
326+
bool falsepositive;
316327
char fast_no_hz[72];
317328
struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
318329
char *ticks_title;
@@ -333,7 +344,9 @@ static void print_cpu_stall_info(int cpu)
333344
}
334345
print_cpu_stall_fast_no_hz(fast_no_hz, cpu);
335346
delta = rcu_seq_ctr(rdp->mynode->gp_seq - rdp->rcu_iw_gp_seq);
336-
pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%ld/%#lx softirq=%u/%u fqs=%ld %s\n",
347+
falsepositive = rcu_is_gp_kthread_starving(NULL) &&
348+
rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp));
349+
pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%03x/%ld/%#lx softirq=%u/%u fqs=%ld %s%s\n",
337350
cpu,
338351
"O."[!!cpu_online(cpu)],
339352
"o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)],
@@ -345,8 +358,9 @@ static void print_cpu_stall_info(int cpu)
345358
rcu_dynticks_snap(rdp) & 0xfff,
346359
rdp->dynticks_nesting, rdp->dynticks_nmi_nesting,
347360
rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
348-
READ_ONCE(rcu_state.n_force_qs) - rcu_state.n_force_qs_gpstart,
349-
fast_no_hz);
361+
data_race(rcu_state.n_force_qs) - rcu_state.n_force_qs_gpstart,
362+
fast_no_hz,
363+
falsepositive ? " (false positive?)" : "");
350364
}
351365

352366
/* Complain about starvation of grace-period kthread. */
@@ -355,15 +369,15 @@ static void rcu_check_gp_kthread_starvation(void)
355369
struct task_struct *gpk = rcu_state.gp_kthread;
356370
unsigned long j;
357371

358-
j = jiffies - READ_ONCE(rcu_state.gp_activity);
359-
if (j > 2 * HZ) {
372+
if (rcu_is_gp_kthread_starving(&j)) {
360373
pr_err("%s kthread starved for %ld jiffies! g%ld f%#x %s(%d) ->state=%#lx ->cpu=%d\n",
361374
rcu_state.name, j,
362375
(long)rcu_seq_current(&rcu_state.gp_seq),
363376
READ_ONCE(rcu_state.gp_flags),
364377
gp_state_getname(rcu_state.gp_state), rcu_state.gp_state,
365378
gpk ? gpk->state : ~0, gpk ? task_cpu(gpk) : -1);
366379
if (gpk) {
380+
pr_err("\tUnless %s kthread gets sufficient CPU time, OOM is now expected behavior.\n", rcu_state.name);
367381
pr_err("RCU grace-period kthread stack dump:\n");
368382
sched_show_task(gpk);
369383
wake_up_process(gpk);

0 commit comments

Comments
 (0)