aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/RCU/torture.txt8
-rw-r--r--kernel/rcutorture.c117
2 files changed, 120 insertions, 5 deletions
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
index af40929e1cb0..d67068d0d2b9 100644
--- a/Documentation/RCU/torture.txt
+++ b/Documentation/RCU/torture.txt
@@ -61,6 +61,14 @@ nreaders This is the number of RCU reading threads supported.
61 To properly exercise RCU implementations with preemptible 61 To properly exercise RCU implementations with preemptible
62 read-side critical sections. 62 read-side critical sections.
63 63
64onoff_interval
65 The number of seconds between each attempt to execute a
66 randomly selected CPU-hotplug operation. Defaults to
67 zero, which disables CPU hotplugging. In HOTPLUG_CPU=n
68 kernels, rcutorture will silently refuse to do any
69 CPU-hotplug operations regardless of what value is
70 specified for onoff_interval.
71
64shuffle_interval 72shuffle_interval
65 The number of seconds to keep the test threads affinitied 73 The number of seconds to keep the test threads affinitied
66 to a particular subset of the CPUs, defaults to 3 seconds. 74 to a particular subset of the CPUs, defaults to 3 seconds.
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index eed9f46eb0a5..1e422ae1506b 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -64,6 +64,7 @@ static int irqreader = 1; /* RCU readers from irq (timers). */
64static int fqs_duration; /* Duration of bursts (us), 0 to disable. */ 64static int fqs_duration; /* Duration of bursts (us), 0 to disable. */
65static int fqs_holdoff; /* Hold time within burst (us). */ 65static int fqs_holdoff; /* Hold time within burst (us). */
66static int fqs_stutter = 3; /* Wait time between bursts (s). */ 66static int fqs_stutter = 3; /* Wait time between bursts (s). */
67static int onoff_interval; /* Wait time between CPU hotplugs, 0=disable. */
67static int shutdown_secs; /* Shutdown time (s). <=0 for no shutdown. */ 68static int shutdown_secs; /* Shutdown time (s). <=0 for no shutdown. */
68static int test_boost = 1; /* Test RCU prio boost: 0=no, 1=maybe, 2=yes. */ 69static int test_boost = 1; /* Test RCU prio boost: 0=no, 1=maybe, 2=yes. */
69static int test_boost_interval = 7; /* Interval between boost tests, seconds. */ 70static int test_boost_interval = 7; /* Interval between boost tests, seconds. */
@@ -92,6 +93,8 @@ module_param(fqs_holdoff, int, 0444);
92MODULE_PARM_DESC(fqs_holdoff, "Holdoff time within fqs bursts (us)"); 93MODULE_PARM_DESC(fqs_holdoff, "Holdoff time within fqs bursts (us)");
93module_param(fqs_stutter, int, 0444); 94module_param(fqs_stutter, int, 0444);
94MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)"); 95MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)");
96module_param(onoff_interval, int, 0444);
97MODULE_PARM_DESC(onoff_interval, "Time between CPU hotplugs (s), 0=disable");
95module_param(shutdown_secs, int, 0444); 98module_param(shutdown_secs, int, 0444);
96MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), zero to disable."); 99MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), zero to disable.");
97module_param(test_boost, int, 0444); 100module_param(test_boost, int, 0444);
@@ -123,6 +126,9 @@ static struct task_struct *stutter_task;
123static struct task_struct *fqs_task; 126static struct task_struct *fqs_task;
124static struct task_struct *boost_tasks[NR_CPUS]; 127static struct task_struct *boost_tasks[NR_CPUS];
125static struct task_struct *shutdown_task; 128static struct task_struct *shutdown_task;
129#ifdef CONFIG_HOTPLUG_CPU
130static struct task_struct *onoff_task;
131#endif /* #ifdef CONFIG_HOTPLUG_CPU */
126 132
127#define RCU_TORTURE_PIPE_LEN 10 133#define RCU_TORTURE_PIPE_LEN 10
128 134
@@ -153,6 +159,10 @@ static long n_rcu_torture_boost_rterror;
153static long n_rcu_torture_boost_failure; 159static long n_rcu_torture_boost_failure;
154static long n_rcu_torture_boosts; 160static long n_rcu_torture_boosts;
155static long n_rcu_torture_timers; 161static long n_rcu_torture_timers;
162static long n_offline_attempts;
163static long n_offline_successes;
164static long n_online_attempts;
165static long n_online_successes;
156static struct list_head rcu_torture_removed; 166static struct list_head rcu_torture_removed;
157static cpumask_var_t shuffle_tmp_mask; 167static cpumask_var_t shuffle_tmp_mask;
158 168
@@ -1084,7 +1094,8 @@ rcu_torture_printk(char *page)
1084 cnt += sprintf(&page[cnt], 1094 cnt += sprintf(&page[cnt],
1085 "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d " 1095 "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d "
1086 "rtmbe: %d rtbke: %ld rtbre: %ld " 1096 "rtmbe: %d rtbke: %ld rtbre: %ld "
1087 "rtbf: %ld rtb: %ld nt: %ld", 1097 "rtbf: %ld rtb: %ld nt: %ld "
1098 "onoff: %ld/%ld:%ld/%ld",
1088 rcu_torture_current, 1099 rcu_torture_current,
1089 rcu_torture_current_version, 1100 rcu_torture_current_version,
1090 list_empty(&rcu_torture_freelist), 1101 list_empty(&rcu_torture_freelist),
@@ -1096,7 +1107,11 @@ rcu_torture_printk(char *page)
1096 n_rcu_torture_boost_rterror, 1107 n_rcu_torture_boost_rterror,
1097 n_rcu_torture_boost_failure, 1108 n_rcu_torture_boost_failure,
1098 n_rcu_torture_boosts, 1109 n_rcu_torture_boosts,
1099 n_rcu_torture_timers); 1110 n_rcu_torture_timers,
1111 n_online_successes,
1112 n_online_attempts,
1113 n_offline_successes,
1114 n_offline_attempts);
1100 if (atomic_read(&n_rcu_torture_mberror) != 0 || 1115 if (atomic_read(&n_rcu_torture_mberror) != 0 ||
1101 n_rcu_torture_boost_ktrerror != 0 || 1116 n_rcu_torture_boost_ktrerror != 0 ||
1102 n_rcu_torture_boost_rterror != 0 || 1117 n_rcu_torture_boost_rterror != 0 ||
@@ -1260,12 +1275,14 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag)
1260 "shuffle_interval=%d stutter=%d irqreader=%d " 1275 "shuffle_interval=%d stutter=%d irqreader=%d "
1261 "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d " 1276 "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "
1262 "test_boost=%d/%d test_boost_interval=%d " 1277 "test_boost=%d/%d test_boost_interval=%d "
1263 "test_boost_duration=%d shutdown_secs=%d\n", 1278 "test_boost_duration=%d shutdown_secs=%d "
1279 "onoff_interval=%d\n",
1264 torture_type, tag, nrealreaders, nfakewriters, 1280 torture_type, tag, nrealreaders, nfakewriters,
1265 stat_interval, verbose, test_no_idle_hz, shuffle_interval, 1281 stat_interval, verbose, test_no_idle_hz, shuffle_interval,
1266 stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter, 1282 stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
1267 test_boost, cur_ops->can_boost, 1283 test_boost, cur_ops->can_boost,
1268 test_boost_interval, test_boost_duration, shutdown_secs); 1284 test_boost_interval, test_boost_duration, shutdown_secs,
1285 onoff_interval);
1269} 1286}
1270 1287
1271static struct notifier_block rcutorture_shutdown_nb = { 1288static struct notifier_block rcutorture_shutdown_nb = {
@@ -1338,7 +1355,7 @@ rcu_torture_shutdown(void *arg)
1338 schedule_timeout_interruptible(delta); 1355 schedule_timeout_interruptible(delta);
1339 jiffies_snap = ACCESS_ONCE(jiffies); 1356 jiffies_snap = ACCESS_ONCE(jiffies);
1340 } 1357 }
1341 if (ULONG_CMP_LT(jiffies, shutdown_time)) { 1358 if (kthread_should_stop()) {
1342 VERBOSE_PRINTK_STRING("rcu_torture_shutdown task stopping"); 1359 VERBOSE_PRINTK_STRING("rcu_torture_shutdown task stopping");
1343 return 0; 1360 return 0;
1344 } 1361 }
@@ -1352,6 +1369,94 @@ rcu_torture_shutdown(void *arg)
1352 return 0; 1369 return 0;
1353} 1370}
1354 1371
1372#ifdef CONFIG_HOTPLUG_CPU
1373
1374/*
1375 * Execute random CPU-hotplug operations at the interval specified
1376 * by the onoff_interval.
1377 */
1378static int
1379rcu_torture_onoff(void *arg)
1380{
1381 int cpu;
1382 int maxcpu = -1;
1383 DEFINE_RCU_RANDOM(rand);
1384
1385 VERBOSE_PRINTK_STRING("rcu_torture_onoff task started");
1386 for_each_online_cpu(cpu)
1387 maxcpu = cpu;
1388 WARN_ON(maxcpu < 0);
1389 while (!kthread_should_stop()) {
1390 cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1);
1391 if (cpu_online(cpu)) {
1392 if (verbose)
1393 printk(KERN_ALERT "%s" TORTURE_FLAG
1394 "rcu_torture_onoff task: offlining %d\n",
1395 torture_type, cpu);
1396 n_offline_attempts++;
1397 if (cpu_down(cpu) == 0) {
1398 if (verbose)
1399 printk(KERN_ALERT "%s" TORTURE_FLAG
1400 "rcu_torture_onoff task: "
1401 "offlined %d\n",
1402 torture_type, cpu);
1403 n_offline_successes++;
1404 }
1405 } else {
1406 if (verbose)
1407 printk(KERN_ALERT "%s" TORTURE_FLAG
1408 "rcu_torture_onoff task: onlining %d\n",
1409 torture_type, cpu);
1410 n_online_attempts++;
1411 if (cpu_up(cpu) == 0) {
1412 if (verbose)
1413 printk(KERN_ALERT "%s" TORTURE_FLAG
1414 "rcu_torture_onoff task: "
1415 "onlined %d\n",
1416 torture_type, cpu);
1417 n_online_successes++;
1418 }
1419 }
1420 schedule_timeout_interruptible(onoff_interval * HZ);
1421 }
1422 VERBOSE_PRINTK_STRING("rcu_torture_onoff task stopping");
1423 return 0;
1424}
1425
1426static int
1427rcu_torture_onoff_init(void)
1428{
1429 if (onoff_interval <= 0)
1430 return 0;
1431 onoff_task = kthread_run(rcu_torture_onoff, NULL, "rcu_torture_onoff");
1432 if (IS_ERR(onoff_task)) {
1433 onoff_task = NULL;
1434 return PTR_ERR(onoff_task);
1435 }
1436 return 0;
1437}
1438
1439static void rcu_torture_onoff_cleanup(void)
1440{
1441 if (onoff_task == NULL)
1442 return;
1443 VERBOSE_PRINTK_STRING("Stopping rcu_torture_onoff task");
1444 kthread_stop(onoff_task);
1445}
1446
1447#else /* #ifdef CONFIG_HOTPLUG_CPU */
1448
1449static void
1450rcu_torture_onoff_init(void)
1451{
1452}
1453
1454static void rcu_torture_onoff_cleanup(void)
1455{
1456}
1457
1458#endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
1459
1355static int rcutorture_cpu_notify(struct notifier_block *self, 1460static int rcutorture_cpu_notify(struct notifier_block *self,
1356 unsigned long action, void *hcpu) 1461 unsigned long action, void *hcpu)
1357{ 1462{
@@ -1460,6 +1565,7 @@ rcu_torture_cleanup(void)
1460 VERBOSE_PRINTK_STRING("Stopping rcu_torture_shutdown task"); 1565 VERBOSE_PRINTK_STRING("Stopping rcu_torture_shutdown task");
1461 kthread_stop(shutdown_task); 1566 kthread_stop(shutdown_task);
1462 } 1567 }
1568 rcu_torture_onoff_cleanup();
1463 1569
1464 /* Wait for all RCU callbacks to fire. */ 1570 /* Wait for all RCU callbacks to fire. */
1465 1571
@@ -1687,6 +1793,7 @@ rcu_torture_init(void)
1687 goto unwind; 1793 goto unwind;
1688 } 1794 }
1689 } 1795 }
1796 rcu_torture_onoff_init();
1690 register_reboot_notifier(&rcutorture_shutdown_nb); 1797 register_reboot_notifier(&rcutorture_shutdown_nb);
1691 rcutorture_record_test_transition(); 1798 rcutorture_record_test_transition();
1692 mutex_unlock(&fullstop_mutex); 1799 mutex_unlock(&fullstop_mutex);