Skip to content

Commit 42a8a26

Browse files
paulmckrcuNeeraj Upadhyay
authored andcommitted
rcuscale: Dump stacks of stalled rcu_scale_writer() instances
This commit improves debuggability by dumping the stacks of rcu_scale_writer() instances that have not completed in a reasonable timeframe. These stacks are dumped remotely, but they will be accurate in the thus-far common case where the stalled rcu_scale_writer() instances are blocked. [ paulmck: Apply kernel test robot feedback. ] Signed-off-by: "Paul E. McKenney" <[email protected]> Signed-off-by: Neeraj Upadhyay <[email protected]>
1 parent ea79376 commit 42a8a26

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

kernel/rcu/rcuscale.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <linux/torture.h>
4040
#include <linux/vmalloc.h>
4141
#include <linux/rcupdate_trace.h>
42+
#include <linux/sched/debug.h>
4243

4344
#include "rcu.h"
4445

@@ -111,6 +112,7 @@ static struct task_struct **reader_tasks;
111112
static struct task_struct *shutdown_task;
112113

113114
static u64 **writer_durations;
115+
static bool *writer_done;
114116
static int *writer_n_durations;
115117
static atomic_t n_rcu_scale_reader_started;
116118
static atomic_t n_rcu_scale_writer_started;
@@ -524,6 +526,7 @@ rcu_scale_writer(void *arg)
524526
started = true;
525527
if (!done && i >= MIN_MEAS && time_after(jiffies, jdone)) {
526528
done = true;
529+
WRITE_ONCE(writer_done[me], true);
527530
sched_set_normal(current, 0);
528531
pr_alert("%s%s rcu_scale_writer %ld has %d measurements\n",
529532
scale_type, SCALE_FLAG, me, MIN_MEAS);
@@ -549,6 +552,19 @@ rcu_scale_writer(void *arg)
549552
if (done && !alldone &&
550553
atomic_read(&n_rcu_scale_writer_finished) >= nrealwriters)
551554
alldone = true;
555+
if (done && !alldone && time_after(jiffies, jdone + HZ * 60)) {
556+
static atomic_t dumped;
557+
int i;
558+
559+
if (!atomic_xchg(&dumped, 1)) {
560+
for (i = 0; i < nrealwriters; i++) {
561+
if (writer_done[i])
562+
continue;
563+
pr_info("%s: Task %ld flags writer %d:\n", __func__, me, i);
564+
sched_show_task(writer_tasks[i]);
565+
}
566+
}
567+
}
552568
if (started && !alldone && i < MAX_MEAS - 1)
553569
i++;
554570
rcu_scale_wait_shutdown();
@@ -921,6 +937,8 @@ rcu_scale_cleanup(void)
921937
kfree(writer_tasks);
922938
kfree(writer_durations);
923939
kfree(writer_n_durations);
940+
kfree(writer_done);
941+
writer_done = NULL;
924942
}
925943

926944
/* Do torture-type-specific cleanup operations. */
@@ -1015,10 +1033,11 @@ rcu_scale_init(void)
10151033
}
10161034
while (atomic_read(&n_rcu_scale_reader_started) < nrealreaders)
10171035
schedule_timeout_uninterruptible(1);
1018-
writer_tasks = kcalloc(nrealwriters, sizeof(reader_tasks[0]), GFP_KERNEL);
1036+
writer_tasks = kcalloc(nrealwriters, sizeof(writer_tasks[0]), GFP_KERNEL);
10191037
writer_durations = kcalloc(nrealwriters, sizeof(*writer_durations), GFP_KERNEL);
10201038
writer_n_durations = kcalloc(nrealwriters, sizeof(*writer_n_durations), GFP_KERNEL);
1021-
if (!writer_tasks || !writer_durations || !writer_n_durations) {
1039+
writer_done = kcalloc(nrealwriters, sizeof(writer_done[0]), GFP_KERNEL);
1040+
if (!writer_tasks || !writer_durations || !writer_n_durations || !writer_done) {
10221041
SCALEOUT_ERRSTRING("out of memory");
10231042
firsterr = -ENOMEM;
10241043
goto unwind;

0 commit comments

Comments
 (0)