mirror of https://gitee.com/openkylin/linux.git
rcutorture: Add flag to produce non-busy-wait task stalls
This commit aids testing of RCU task stall warning messages by adding an rcutorture.stall_cpu_block module parameter that results in the induced stall sleeping within the RCU read-side critical section. Spinning with interrupts disabled is still available via the rcutorture.stall_cpu_irqsoff module parameter, and specifying neither of these two module parameters will spin with preemption disabled. Note that sleeping (as opposed to preemption) results in additional complaints from RCU at context-switch time, so yet more testing. Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
parent
be44ae6243
commit
19a8ff956c
|
@ -4210,6 +4210,11 @@
|
||||||
Duration of CPU stall (s) to test RCU CPU stall
|
Duration of CPU stall (s) to test RCU CPU stall
|
||||||
warnings, zero to disable.
|
warnings, zero to disable.
|
||||||
|
|
||||||
|
rcutorture.stall_cpu_block= [KNL]
|
||||||
|
Sleep while stalling if set. This will result
|
||||||
|
in warnings from preemptible RCU in addition
|
||||||
|
to any other stall-related activity.
|
||||||
|
|
||||||
rcutorture.stall_cpu_holdoff= [KNL]
|
rcutorture.stall_cpu_holdoff= [KNL]
|
||||||
Time to wait (s) after boot before inducing stall.
|
Time to wait (s) after boot before inducing stall.
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ torture_param(int, stall_cpu, 0, "Stall duration (s), zero to disable.");
|
||||||
torture_param(int, stall_cpu_holdoff, 10,
|
torture_param(int, stall_cpu_holdoff, 10,
|
||||||
"Time to wait before starting stall (s).");
|
"Time to wait before starting stall (s).");
|
||||||
torture_param(int, stall_cpu_irqsoff, 0, "Disable interrupts while stalling.");
|
torture_param(int, stall_cpu_irqsoff, 0, "Disable interrupts while stalling.");
|
||||||
|
torture_param(int, stall_cpu_block, 0, "Sleep while stalling.");
|
||||||
torture_param(int, stat_interval, 60,
|
torture_param(int, stat_interval, 60,
|
||||||
"Number of seconds between stats printk()s");
|
"Number of seconds between stats printk()s");
|
||||||
torture_param(int, stutter, 5, "Number of seconds to run/halt test");
|
torture_param(int, stutter, 5, "Number of seconds to run/halt test");
|
||||||
|
@ -1548,6 +1549,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
|
||||||
"test_boost=%d/%d test_boost_interval=%d "
|
"test_boost=%d/%d test_boost_interval=%d "
|
||||||
"test_boost_duration=%d shutdown_secs=%d "
|
"test_boost_duration=%d shutdown_secs=%d "
|
||||||
"stall_cpu=%d stall_cpu_holdoff=%d stall_cpu_irqsoff=%d "
|
"stall_cpu=%d stall_cpu_holdoff=%d stall_cpu_irqsoff=%d "
|
||||||
|
"stall_cpu_block=%d "
|
||||||
"n_barrier_cbs=%d "
|
"n_barrier_cbs=%d "
|
||||||
"onoff_interval=%d onoff_holdoff=%d\n",
|
"onoff_interval=%d onoff_holdoff=%d\n",
|
||||||
torture_type, tag, nrealreaders, nfakewriters,
|
torture_type, tag, nrealreaders, nfakewriters,
|
||||||
|
@ -1556,6 +1558,7 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
|
||||||
test_boost, cur_ops->can_boost,
|
test_boost, cur_ops->can_boost,
|
||||||
test_boost_interval, test_boost_duration, shutdown_secs,
|
test_boost_interval, test_boost_duration, shutdown_secs,
|
||||||
stall_cpu, stall_cpu_holdoff, stall_cpu_irqsoff,
|
stall_cpu, stall_cpu_holdoff, stall_cpu_irqsoff,
|
||||||
|
stall_cpu_block,
|
||||||
n_barrier_cbs,
|
n_barrier_cbs,
|
||||||
onoff_interval, onoff_holdoff);
|
onoff_interval, onoff_holdoff);
|
||||||
}
|
}
|
||||||
|
@ -1611,6 +1614,7 @@ static int rcutorture_booster_init(unsigned int cpu)
|
||||||
*/
|
*/
|
||||||
static int rcu_torture_stall(void *args)
|
static int rcu_torture_stall(void *args)
|
||||||
{
|
{
|
||||||
|
int idx;
|
||||||
unsigned long stop_at;
|
unsigned long stop_at;
|
||||||
|
|
||||||
VERBOSE_TOROUT_STRING("rcu_torture_stall task started");
|
VERBOSE_TOROUT_STRING("rcu_torture_stall task started");
|
||||||
|
@ -1622,21 +1626,22 @@ static int rcu_torture_stall(void *args)
|
||||||
if (!kthread_should_stop()) {
|
if (!kthread_should_stop()) {
|
||||||
stop_at = ktime_get_seconds() + stall_cpu;
|
stop_at = ktime_get_seconds() + stall_cpu;
|
||||||
/* RCU CPU stall is expected behavior in following code. */
|
/* RCU CPU stall is expected behavior in following code. */
|
||||||
rcu_read_lock();
|
idx = cur_ops->readlock();
|
||||||
if (stall_cpu_irqsoff)
|
if (stall_cpu_irqsoff)
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
else
|
else if (!stall_cpu_block)
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
pr_alert("rcu_torture_stall start on CPU %d.\n",
|
pr_alert("rcu_torture_stall start on CPU %d.\n",
|
||||||
smp_processor_id());
|
raw_smp_processor_id());
|
||||||
while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(),
|
while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(),
|
||||||
stop_at))
|
stop_at))
|
||||||
continue; /* Induce RCU CPU stall warning. */
|
if (stall_cpu_block)
|
||||||
|
schedule_timeout_uninterruptible(HZ);
|
||||||
if (stall_cpu_irqsoff)
|
if (stall_cpu_irqsoff)
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
else
|
else if (!stall_cpu_block)
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
rcu_read_unlock();
|
cur_ops->readunlock(idx);
|
||||||
pr_alert("rcu_torture_stall end.\n");
|
pr_alert("rcu_torture_stall end.\n");
|
||||||
}
|
}
|
||||||
torture_shutdown_absorb("rcu_torture_stall");
|
torture_shutdown_absorb("rcu_torture_stall");
|
||||||
|
|
Loading…
Reference in New Issue