diff options
Diffstat (limited to 'kernel/rcu/rcutorture.c')
-rw-r--r-- | kernel/rcu/rcutorture.c | 62 |
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 | ||
1365 | static void rcutorture_booster_cleanup(int cpu) | 1369 | static 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 | ||
1380 | static int rcutorture_booster_init(int cpu) | 1385 | static 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 | ||
1580 | static int rcutorture_cpu_notify(struct notifier_block *self, | 1585 | static 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 | |||
1599 | static struct notifier_block rcutorture_cpu_nb = { | ||
1600 | .notifier_call = rcutorture_cpu_notify, | ||
1601 | }; | ||
1602 | 1586 | ||
1603 | static void | 1587 | static void |
1604 | rcu_torture_cleanup(void) | 1588 | rcu_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) |