aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2012-01-20 18:36:33 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-02-21 12:03:52 -0500
commitc13f3757d0fcdcc2b7fc5d5e38da76b8913e6648 (patch)
tree7ae68a12459fc4f18b87fa1a44239e29f82cd244
parent105617da8dc0ae3cf5f5a581330b1e4846fe87f2 (diff)
rcu: Add CPU-stall capability to rcutorture
Add module parameters to rcutorture that induce a CPU stall. The stall_cpu parameter specifies how long to stall in seconds, defaulting to zero, which indicates no stalling is to be undertaken. The stall_cpu_holdoff parameter specifies how many seconds after insmod (or boot, if rcutorture is built into the kernel) that this stall is to start. The default value for stall_cpu_holdoff is ten seconds. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--Documentation/RCU/torture.txt18
-rw-r--r--kernel/rcutorture.c66
2 files changed, 84 insertions, 0 deletions
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
index d25be872ae33..375d3fb71437 100644
--- a/Documentation/RCU/torture.txt
+++ b/Documentation/RCU/torture.txt
@@ -86,6 +86,24 @@ shutdown_secs The number of seconds to run the test before terminating
86 zero, which disables test termination and system shutdown. 86 zero, which disables test termination and system shutdown.
87 This capability is useful for automated testing. 87 This capability is useful for automated testing.
88 88
89stall_cpu The number of seconds that a CPU should be stalled while
90 within both an rcu_read_lock() and a preempt_disable().
91 This stall happens only once per rcutorture run.
92 If you need multiple stalls, use modprobe and rmmod to
93 repeatedly run rcutorture. The default for stall_cpu
94 is zero, which prevents rcutorture from stalling a CPU.
95
96 Note that attempts to rmmod rcutorture while the stall
97 is ongoing will hang, so be careful what value you
98 choose for this module parameter! In addition, too-large
99 values for stall_cpu might well induce failures and
100 warnings in other parts of the kernel. You have been
101 warned!
102
103stall_cpu_holdoff
104 The number of seconds to wait after rcutorture starts
105 before stalling a CPU. Defaults to 10 seconds.
106
89stat_interval The number of seconds between output of torture 107stat_interval The number of seconds between output of torture
90 statistics (via printk()). Regardless of the interval, 108 statistics (via printk()). Regardless of the interval,
91 statistics are printed when the module is unloaded. 109 statistics are printed when the module is unloaded.
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 2914cafe171b..5cfa23be43bd 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -67,6 +67,8 @@ static int fqs_stutter = 3; /* Wait time between bursts (s). */
67static int onoff_interval; /* Wait time between CPU hotplugs, 0=disable. */ 67static int onoff_interval; /* Wait time between CPU hotplugs, 0=disable. */
68static int onoff_holdoff; /* Seconds after boot before CPU hotplugs. */ 68static int onoff_holdoff; /* Seconds after boot before CPU hotplugs. */
69static int shutdown_secs; /* Shutdown time (s). <=0 for no shutdown. */ 69static int shutdown_secs; /* Shutdown time (s). <=0 for no shutdown. */
70static int stall_cpu; /* CPU-stall duration (s). 0 for no stall. */
71static int stall_cpu_holdoff = 10; /* Time to wait until stall (s). */
70static int test_boost = 1; /* Test RCU prio boost: 0=no, 1=maybe, 2=yes. */ 72static int test_boost = 1; /* Test RCU prio boost: 0=no, 1=maybe, 2=yes. */
71static int test_boost_interval = 7; /* Interval between boost tests, seconds. */ 73static int test_boost_interval = 7; /* Interval between boost tests, seconds. */
72static int test_boost_duration = 4; /* Duration of each boost test, seconds. */ 74static int test_boost_duration = 4; /* Duration of each boost test, seconds. */
@@ -100,6 +102,10 @@ module_param(onoff_holdoff, int, 0444);
100MODULE_PARM_DESC(onoff_holdoff, "Time after boot before CPU hotplugs (s)"); 102MODULE_PARM_DESC(onoff_holdoff, "Time after boot before CPU hotplugs (s)");
101module_param(shutdown_secs, int, 0444); 103module_param(shutdown_secs, int, 0444);
102MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), zero to disable."); 104MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), zero to disable.");
105module_param(stall_cpu, int, 0444);
106MODULE_PARM_DESC(stall_cpu, "Stall duration (s), zero to disable.");
107module_param(stall_cpu_holdoff, int, 0444);
108MODULE_PARM_DESC(stall_cpu_holdoff, "Time to wait before starting stall (s).");
103module_param(test_boost, int, 0444); 109module_param(test_boost, int, 0444);
104MODULE_PARM_DESC(test_boost, "Test RCU prio boost: 0=no, 1=maybe, 2=yes."); 110MODULE_PARM_DESC(test_boost, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
105module_param(test_boost_interval, int, 0444); 111module_param(test_boost_interval, int, 0444);
@@ -132,6 +138,7 @@ static struct task_struct *shutdown_task;
132#ifdef CONFIG_HOTPLUG_CPU 138#ifdef CONFIG_HOTPLUG_CPU
133static struct task_struct *onoff_task; 139static struct task_struct *onoff_task;
134#endif /* #ifdef CONFIG_HOTPLUG_CPU */ 140#endif /* #ifdef CONFIG_HOTPLUG_CPU */
141static struct task_struct *stall_task;
135 142
136#define RCU_TORTURE_PIPE_LEN 10 143#define RCU_TORTURE_PIPE_LEN 10
137 144
@@ -1489,6 +1496,63 @@ static void rcu_torture_onoff_cleanup(void)
1489 1496
1490#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */ 1497#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
1491 1498
1499/*
1500 * CPU-stall kthread. It waits as specified by stall_cpu_holdoff, then
1501 * induces a CPU stall for the time specified by stall_cpu.
1502 */
1503static int __cpuinit rcu_torture_stall(void *args)
1504{
1505 unsigned long stop_at;
1506
1507 VERBOSE_PRINTK_STRING("rcu_torture_stall task started");
1508 if (stall_cpu_holdoff > 0) {
1509 VERBOSE_PRINTK_STRING("rcu_torture_stall begin holdoff");
1510 schedule_timeout_interruptible(stall_cpu_holdoff * HZ);
1511 VERBOSE_PRINTK_STRING("rcu_torture_stall end holdoff");
1512 }
1513 if (!kthread_should_stop()) {
1514 stop_at = get_seconds() + stall_cpu;
1515 /* RCU CPU stall is expected behavior in following code. */
1516 printk(KERN_ALERT "rcu_torture_stall start.\n");
1517 rcu_read_lock();
1518 preempt_disable();
1519 while (ULONG_CMP_LT(get_seconds(), stop_at))
1520 continue; /* Induce RCU CPU stall warning. */
1521 preempt_enable();
1522 rcu_read_unlock();
1523 printk(KERN_ALERT "rcu_torture_stall end.\n");
1524 }
1525 rcutorture_shutdown_absorb("rcu_torture_stall");
1526 while (!kthread_should_stop())
1527 schedule_timeout_interruptible(10 * HZ);
1528 return 0;
1529}
1530
1531/* Spawn CPU-stall kthread, if stall_cpu specified. */
1532static int __init rcu_torture_stall_init(void)
1533{
1534 int ret;
1535
1536 if (stall_cpu <= 0)
1537 return 0;
1538 stall_task = kthread_run(rcu_torture_stall, NULL, "rcu_torture_stall");
1539 if (IS_ERR(stall_task)) {
1540 ret = PTR_ERR(stall_task);
1541 stall_task = NULL;
1542 return ret;
1543 }
1544 return 0;
1545}
1546
1547/* Clean up after the CPU-stall kthread, if one was spawned. */
1548static void rcu_torture_stall_cleanup(void)
1549{
1550 if (stall_task == NULL)
1551 return;
1552 VERBOSE_PRINTK_STRING("Stopping rcu_torture_stall_task.");
1553 kthread_stop(stall_task);
1554}
1555
1492static int rcutorture_cpu_notify(struct notifier_block *self, 1556static int rcutorture_cpu_notify(struct notifier_block *self,
1493 unsigned long action, void *hcpu) 1557 unsigned long action, void *hcpu)
1494{ 1558{
@@ -1531,6 +1595,7 @@ rcu_torture_cleanup(void)
1531 fullstop = FULLSTOP_RMMOD; 1595 fullstop = FULLSTOP_RMMOD;
1532 mutex_unlock(&fullstop_mutex); 1596 mutex_unlock(&fullstop_mutex);
1533 unregister_reboot_notifier(&rcutorture_shutdown_nb); 1597 unregister_reboot_notifier(&rcutorture_shutdown_nb);
1598 rcu_torture_stall_cleanup();
1534 if (stutter_task) { 1599 if (stutter_task) {
1535 VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task"); 1600 VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task");
1536 kthread_stop(stutter_task); 1601 kthread_stop(stutter_task);
@@ -1831,6 +1896,7 @@ rcu_torture_init(void)
1831 } 1896 }
1832 rcu_torture_onoff_init(); 1897 rcu_torture_onoff_init();
1833 register_reboot_notifier(&rcutorture_shutdown_nb); 1898 register_reboot_notifier(&rcutorture_shutdown_nb);
1899 rcu_torture_stall_init();
1834 rcutorture_record_test_transition(); 1900 rcutorture_record_test_transition();
1835 mutex_unlock(&fullstop_mutex); 1901 mutex_unlock(&fullstop_mutex);
1836 return 0; 1902 return 0;