Skip to content

Commit 92987fe

Browse files
committed
rcu: Allow expedited RCU CPU stall warnings to dump task stacks
This commit introduces the rcupdate.rcu_exp_stall_task_details kernel boot parameter, which cause expedited RCU CPU stall warnings to dump the stacks of any tasks blocking the current expedited grace period. Reported-by: David Howells <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 748bf47 commit 92987fe

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5113,6 +5113,11 @@
51135113
rcupdate.rcu_cpu_stall_timeout to be used (after
51145114
conversion from seconds to milliseconds).
51155115

5116+
rcupdate.rcu_exp_stall_task_details= [KNL]
5117+
Print stack dumps of any tasks blocking the
5118+
current expedited RCU grace period during an
5119+
expedited RCU CPU stall warning.
5120+
51165121
rcupdate.rcu_expedited= [KNL]
51175122
Use expedited grace-period primitives, for
51185123
example, synchronize_rcu_expedited() instead

kernel/rcu/rcu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ extern int rcu_cpu_stall_ftrace_dump;
224224
extern int rcu_cpu_stall_suppress;
225225
extern int rcu_cpu_stall_timeout;
226226
extern int rcu_exp_cpu_stall_timeout;
227+
extern bool rcu_exp_stall_task_details __read_mostly;
227228
int rcu_jiffies_till_stall_check(void);
228229
int rcu_exp_jiffies_till_stall_check(void);
229230

kernel/rcu/tree_exp.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
static void rcu_exp_handler(void *unused);
1313
static int rcu_print_task_exp_stall(struct rcu_node *rnp);
14+
static void rcu_exp_print_detail_task_stall_rnp(struct rcu_node *rnp);
1415

1516
/*
1617
* Record the start of an expedited grace period.
@@ -671,6 +672,7 @@ static void synchronize_rcu_expedited_wait(void)
671672
dump_cpu_task(cpu);
672673
preempt_enable();
673674
}
675+
rcu_exp_print_detail_task_stall_rnp(rnp);
674676
}
675677
jiffies_stall = 3 * rcu_exp_jiffies_till_stall_check() + 3;
676678
panic_on_rcu_stall();
@@ -813,6 +815,36 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp)
813815
return ndetected;
814816
}
815817

818+
/*
819+
* Scan the current list of tasks blocked within RCU read-side critical
820+
* sections, dumping the stack of each that is blocking the current
821+
* expedited grace period.
822+
*/
823+
static void rcu_exp_print_detail_task_stall_rnp(struct rcu_node *rnp)
824+
{
825+
unsigned long flags;
826+
struct task_struct *t;
827+
828+
if (!rcu_exp_stall_task_details)
829+
return;
830+
raw_spin_lock_irqsave_rcu_node(rnp, flags);
831+
if (!READ_ONCE(rnp->exp_tasks)) {
832+
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
833+
return;
834+
}
835+
t = list_entry(rnp->exp_tasks->prev,
836+
struct task_struct, rcu_node_entry);
837+
list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
838+
/*
839+
* We could be printing a lot while holding a spinlock.
840+
* Avoid triggering hard lockup.
841+
*/
842+
touch_nmi_watchdog();
843+
sched_show_task(t);
844+
}
845+
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
846+
}
847+
816848
#else /* #ifdef CONFIG_PREEMPT_RCU */
817849

818850
/* Request an expedited quiescent state. */
@@ -885,6 +917,15 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp)
885917
return 0;
886918
}
887919

920+
/*
921+
* Because preemptible RCU does not exist, we never have to print out
922+
* tasks blocked within RCU read-side critical sections that are blocking
923+
* the current expedited grace period.
924+
*/
925+
static void rcu_exp_print_detail_task_stall_rnp(struct rcu_node *rnp)
926+
{
927+
}
928+
888929
#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
889930

890931
/**

kernel/rcu/update.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,8 @@ int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
509509
module_param(rcu_cpu_stall_timeout, int, 0644);
510510
int rcu_exp_cpu_stall_timeout __read_mostly = CONFIG_RCU_EXP_CPU_STALL_TIMEOUT;
511511
module_param(rcu_exp_cpu_stall_timeout, int, 0644);
512+
bool rcu_exp_stall_task_details __read_mostly;
513+
module_param(rcu_exp_stall_task_details, bool, 0644);
512514
#endif /* #ifdef CONFIG_RCU_STALL_COMMON */
513515

514516
// Suppress boot-time RCU CPU stall warnings and rcutorture writer stall

0 commit comments

Comments
 (0)