Skip to content

Commit

Permalink
rcutorture: Add test_nmis module parameter
Browse files Browse the repository at this point in the history
This commit adds a test_nmis module parameter to generate the specified
number of NMI stack backtraces 15 seconds apart.  This module parameter
can be used to test NMI delivery and accompanying diagnostics.

It also forces NMI backtraces in the case where the destination CPU is
idle, thus avoiding the occasional annoying failure to actually send
an NMI.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
  • Loading branch information
paulmckrcu committed Jan 20, 2023
1 parent 344da54 commit 0b42742
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
28 changes: 26 additions & 2 deletions kernel/rcu/rcutorture.c
Expand Up @@ -119,6 +119,7 @@ torture_param(int, stutter, 5, "Number of seconds to run/halt test");
torture_param(int, test_boost, 1, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
torture_param(int, test_boost_duration, 4, "Duration of each boost test, seconds.");
torture_param(int, test_boost_interval, 7, "Interval between boost tests, seconds.");
torture_param(int, test_nmis, 0, "End-test NMI tests, 0 to disable.");
torture_param(bool, test_no_idle_hz, true, "Test support for tickless idle CPUs");
torture_param(int, verbose, 1, "Enable verbose debugging printk()s");

Expand Down Expand Up @@ -2358,7 +2359,8 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
"n_barrier_cbs=%d "
"onoff_interval=%d onoff_holdoff=%d "
"read_exit_delay=%d read_exit_burst=%d "
"nocbs_nthreads=%d nocbs_toggle=%d\n",
"nocbs_nthreads=%d nocbs_toggle=%d "
"test_nmis=%d\n",
torture_type, tag, nrealreaders, nfakewriters,
stat_interval, verbose, test_no_idle_hz, shuffle_interval,
stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
Expand All @@ -2369,7 +2371,8 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
n_barrier_cbs,
onoff_interval, onoff_holdoff,
read_exit_delay, read_exit_burst,
nocbs_nthreads, nocbs_toggle);
nocbs_nthreads, nocbs_toggle,
test_nmis);
}

static int rcutorture_booster_cleanup(unsigned int cpu)
Expand Down Expand Up @@ -3273,6 +3276,25 @@ static void rcu_torture_read_exit_cleanup(void)
torture_stop_kthread(rcutorture_read_exit, read_exit_task);
}

static void rcutorture_test_nmis(int n)
{
int cpu;
int dumpcpu;
int i;

for (i = 0; i < n; i++) {
preempt_disable();
cpu = smp_processor_id();
dumpcpu = cpu + 1;
if (dumpcpu >= nr_cpu_ids)
dumpcpu = 0;
pr_alert("%s: CPU %d invoking dump_cpu_task(%d)\n", __func__, cpu, dumpcpu);
dump_cpu_task(dumpcpu);
preempt_enable();
schedule_timeout_uninterruptible(15 * HZ);
}
}

static enum cpuhp_state rcutor_hp;

static void
Expand All @@ -3297,6 +3319,8 @@ rcu_torture_cleanup(void)
return;
}

rcutorture_test_nmis(test_nmis);

if (cur_ops->gp_kthread_dbg)
cur_ops->gp_kthread_dbg();
rcu_torture_read_exit_cleanup();
Expand Down
15 changes: 5 additions & 10 deletions lib/nmi_backtrace.c
Expand Up @@ -102,16 +102,11 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
* against other CPUs.
*/
printk_cpu_sync_get_irqsave(flags);
if (!READ_ONCE(backtrace_idle) && regs && cpu_in_idle(instruction_pointer(regs))) {
pr_warn("NMI backtrace for cpu %d skipped: idling at %pS\n",
cpu, (void *)instruction_pointer(regs));
} else {
pr_warn("NMI backtrace for cpu %d\n", cpu);
if (regs)
show_regs(regs);
else
dump_stack();
}
pr_warn("NMI backtrace for cpu %d\n", cpu);
if (regs)
show_regs(regs);
else
dump_stack();
printk_cpu_sync_put_irqrestore(flags);
cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
return true;
Expand Down

0 comments on commit 0b42742

Please sign in to comment.