aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/rcutorture.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcu/rcutorture.c')
-rw-r--r--kernel/rcu/rcutorture.c62
1 files changed, 21 insertions, 41 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 971e2b138063..bf08fee53dc7 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1238,6 +1238,7 @@ rcu_torture_stats_print(void)
1238 long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; 1238 long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
1239 long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 }; 1239 long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
1240 static unsigned long rtcv_snap = ULONG_MAX; 1240 static unsigned long rtcv_snap = ULONG_MAX;
1241 struct task_struct *wtp;
1241 1242
1242 for_each_possible_cpu(cpu) { 1243 for_each_possible_cpu(cpu) {
1243 for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) { 1244 for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
@@ -1258,8 +1259,9 @@ rcu_torture_stats_print(void)
1258 atomic_read(&n_rcu_torture_alloc), 1259 atomic_read(&n_rcu_torture_alloc),
1259 atomic_read(&n_rcu_torture_alloc_fail), 1260 atomic_read(&n_rcu_torture_alloc_fail),
1260 atomic_read(&n_rcu_torture_free)); 1261 atomic_read(&n_rcu_torture_free));
1261 pr_cont("rtmbe: %d rtbke: %ld rtbre: %ld ", 1262 pr_cont("rtmbe: %d rtbe: %ld rtbke: %ld rtbre: %ld ",
1262 atomic_read(&n_rcu_torture_mberror), 1263 atomic_read(&n_rcu_torture_mberror),
1264 n_rcu_torture_barrier_error,
1263 n_rcu_torture_boost_ktrerror, 1265 n_rcu_torture_boost_ktrerror,
1264 n_rcu_torture_boost_rterror); 1266 n_rcu_torture_boost_rterror);
1265 pr_cont("rtbf: %ld rtb: %ld nt: %ld ", 1267 pr_cont("rtbf: %ld rtb: %ld nt: %ld ",
@@ -1312,10 +1314,12 @@ rcu_torture_stats_print(void)
1312 1314
1313 rcutorture_get_gp_data(cur_ops->ttype, 1315 rcutorture_get_gp_data(cur_ops->ttype,
1314 &flags, &gpnum, &completed); 1316 &flags, &gpnum, &completed);
1315 pr_alert("??? Writer stall state %s(%d) g%lu c%lu f%#x\n", 1317 wtp = READ_ONCE(writer_task);
1318 pr_alert("??? Writer stall state %s(%d) g%lu c%lu f%#x ->state %#lx\n",
1316 rcu_torture_writer_state_getname(), 1319 rcu_torture_writer_state_getname(),
1317 rcu_torture_writer_state, 1320 rcu_torture_writer_state,
1318 gpnum, completed, flags); 1321 gpnum, completed, flags,
1322 wtp == NULL ? ~0UL : wtp->state);
1319 show_rcu_gp_kthreads(); 1323 show_rcu_gp_kthreads();
1320 rcu_ftrace_dump(DUMP_ALL); 1324 rcu_ftrace_dump(DUMP_ALL);
1321 } 1325 }
@@ -1362,12 +1366,12 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
1362 onoff_interval, onoff_holdoff); 1366 onoff_interval, onoff_holdoff);
1363} 1367}
1364 1368
1365static void rcutorture_booster_cleanup(int cpu) 1369static int rcutorture_booster_cleanup(unsigned int cpu)
1366{ 1370{
1367 struct task_struct *t; 1371 struct task_struct *t;
1368 1372
1369 if (boost_tasks[cpu] == NULL) 1373 if (boost_tasks[cpu] == NULL)
1370 return; 1374 return 0;
1371 mutex_lock(&boost_mutex); 1375 mutex_lock(&boost_mutex);
1372 t = boost_tasks[cpu]; 1376 t = boost_tasks[cpu];
1373 boost_tasks[cpu] = NULL; 1377 boost_tasks[cpu] = NULL;
@@ -1375,9 +1379,10 @@ static void rcutorture_booster_cleanup(int cpu)
1375 1379
1376 /* This must be outside of the mutex, otherwise deadlock! */ 1380 /* This must be outside of the mutex, otherwise deadlock! */
1377 torture_stop_kthread(rcu_torture_boost, t); 1381 torture_stop_kthread(rcu_torture_boost, t);
1382 return 0;
1378} 1383}
1379 1384
1380static int rcutorture_booster_init(int cpu) 1385static int rcutorture_booster_init(unsigned int cpu)
1381{ 1386{
1382 int retval; 1387 int retval;
1383 1388
@@ -1577,28 +1582,7 @@ static void rcu_torture_barrier_cleanup(void)
1577 } 1582 }
1578} 1583}
1579 1584
1580static int rcutorture_cpu_notify(struct notifier_block *self, 1585static enum cpuhp_state rcutor_hp;
1581 unsigned long action, void *hcpu)
1582{
1583 long cpu = (long)hcpu;
1584
1585 switch (action & ~CPU_TASKS_FROZEN) {
1586 case CPU_ONLINE:
1587 case CPU_DOWN_FAILED:
1588 (void)rcutorture_booster_init(cpu);
1589 break;
1590 case CPU_DOWN_PREPARE:
1591 rcutorture_booster_cleanup(cpu);
1592 break;
1593 default:
1594 break;
1595 }
1596 return NOTIFY_OK;
1597}
1598
1599static struct notifier_block rcutorture_cpu_nb = {
1600 .notifier_call = rcutorture_cpu_notify,
1601};
1602 1586
1603static void 1587static void
1604rcu_torture_cleanup(void) 1588rcu_torture_cleanup(void)
@@ -1638,11 +1622,8 @@ rcu_torture_cleanup(void)
1638 for (i = 0; i < ncbflooders; i++) 1622 for (i = 0; i < ncbflooders; i++)
1639 torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]); 1623 torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]);
1640 if ((test_boost == 1 && cur_ops->can_boost) || 1624 if ((test_boost == 1 && cur_ops->can_boost) ||
1641 test_boost == 2) { 1625 test_boost == 2)
1642 unregister_cpu_notifier(&rcutorture_cpu_nb); 1626 cpuhp_remove_state(rcutor_hp);
1643 for_each_possible_cpu(i)
1644 rcutorture_booster_cleanup(i);
1645 }
1646 1627
1647 /* 1628 /*
1648 * Wait for all RCU callbacks to fire, then do flavor-specific 1629 * Wait for all RCU callbacks to fire, then do flavor-specific
@@ -1869,14 +1850,13 @@ rcu_torture_init(void)
1869 test_boost == 2) { 1850 test_boost == 2) {
1870 1851
1871 boost_starttime = jiffies + test_boost_interval * HZ; 1852 boost_starttime = jiffies + test_boost_interval * HZ;
1872 register_cpu_notifier(&rcutorture_cpu_nb); 1853
1873 for_each_possible_cpu(i) { 1854 firsterr = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "RCU_TORTURE",
1874 if (cpu_is_offline(i)) 1855 rcutorture_booster_init,
1875 continue; /* Heuristic: CPU can go offline. */ 1856 rcutorture_booster_cleanup);
1876 firsterr = rcutorture_booster_init(i); 1857 if (firsterr < 0)
1877 if (firsterr) 1858 goto unwind;
1878 goto unwind; 1859 rcutor_hp = firsterr;
1879 }
1880 } 1860 }
1881 firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup); 1861 firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
1882 if (firsterr) 1862 if (firsterr)