diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-08-18 08:57:22 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2016-08-22 12:52:12 -0400 |
commit | 0ffd374b2207a1a0cba9f2dbcc799198482391d5 (patch) | |
tree | 79caa1cbb1cec8046fd2afe0ff4c70e86592f7d0 | |
parent | 0c6d4576c45736f829dc3390ac95181b2ed21bc7 (diff) |
rcutorture: Convert to hotplug state machine
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r-- | kernel/rcu/rcutorture.c | 52 |
1 files changed, 14 insertions, 38 deletions
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 971e2b138063..dc9814860645 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c | |||
@@ -1362,12 +1362,12 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag) | |||
1362 | onoff_interval, onoff_holdoff); | 1362 | onoff_interval, onoff_holdoff); |
1363 | } | 1363 | } |
1364 | 1364 | ||
1365 | static void rcutorture_booster_cleanup(int cpu) | 1365 | static int rcutorture_booster_cleanup(unsigned int cpu) |
1366 | { | 1366 | { |
1367 | struct task_struct *t; | 1367 | struct task_struct *t; |
1368 | 1368 | ||
1369 | if (boost_tasks[cpu] == NULL) | 1369 | if (boost_tasks[cpu] == NULL) |
1370 | return; | 1370 | return 0; |
1371 | mutex_lock(&boost_mutex); | 1371 | mutex_lock(&boost_mutex); |
1372 | t = boost_tasks[cpu]; | 1372 | t = boost_tasks[cpu]; |
1373 | boost_tasks[cpu] = NULL; | 1373 | boost_tasks[cpu] = NULL; |
@@ -1375,9 +1375,10 @@ static void rcutorture_booster_cleanup(int cpu) | |||
1375 | 1375 | ||
1376 | /* This must be outside of the mutex, otherwise deadlock! */ | 1376 | /* This must be outside of the mutex, otherwise deadlock! */ |
1377 | torture_stop_kthread(rcu_torture_boost, t); | 1377 | torture_stop_kthread(rcu_torture_boost, t); |
1378 | return 0; | ||
1378 | } | 1379 | } |
1379 | 1380 | ||
1380 | static int rcutorture_booster_init(int cpu) | 1381 | static int rcutorture_booster_init(unsigned int cpu) |
1381 | { | 1382 | { |
1382 | int retval; | 1383 | int retval; |
1383 | 1384 | ||
@@ -1577,28 +1578,7 @@ static void rcu_torture_barrier_cleanup(void) | |||
1577 | } | 1578 | } |
1578 | } | 1579 | } |
1579 | 1580 | ||
1580 | static int rcutorture_cpu_notify(struct notifier_block *self, | 1581 | 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 | 1582 | ||
1603 | static void | 1583 | static void |
1604 | rcu_torture_cleanup(void) | 1584 | rcu_torture_cleanup(void) |
@@ -1638,11 +1618,8 @@ rcu_torture_cleanup(void) | |||
1638 | for (i = 0; i < ncbflooders; i++) | 1618 | for (i = 0; i < ncbflooders; i++) |
1639 | torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]); | 1619 | torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]); |
1640 | if ((test_boost == 1 && cur_ops->can_boost) || | 1620 | if ((test_boost == 1 && cur_ops->can_boost) || |
1641 | test_boost == 2) { | 1621 | test_boost == 2) |
1642 | unregister_cpu_notifier(&rcutorture_cpu_nb); | 1622 | cpuhp_remove_state(rcutor_hp); |
1643 | for_each_possible_cpu(i) | ||
1644 | rcutorture_booster_cleanup(i); | ||
1645 | } | ||
1646 | 1623 | ||
1647 | /* | 1624 | /* |
1648 | * Wait for all RCU callbacks to fire, then do flavor-specific | 1625 | * Wait for all RCU callbacks to fire, then do flavor-specific |
@@ -1869,14 +1846,13 @@ rcu_torture_init(void) | |||
1869 | test_boost == 2) { | 1846 | test_boost == 2) { |
1870 | 1847 | ||
1871 | boost_starttime = jiffies + test_boost_interval * HZ; | 1848 | boost_starttime = jiffies + test_boost_interval * HZ; |
1872 | register_cpu_notifier(&rcutorture_cpu_nb); | 1849 | |
1873 | for_each_possible_cpu(i) { | 1850 | firsterr = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "RCU_TORTURE", |
1874 | if (cpu_is_offline(i)) | 1851 | rcutorture_booster_init, |
1875 | continue; /* Heuristic: CPU can go offline. */ | 1852 | rcutorture_booster_cleanup); |
1876 | firsterr = rcutorture_booster_init(i); | 1853 | if (firsterr < 0) |
1877 | if (firsterr) | 1854 | goto unwind; |
1878 | goto unwind; | 1855 | rcutor_hp = firsterr; |
1879 | } | ||
1880 | } | 1856 | } |
1881 | firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup); | 1857 | firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup); |
1882 | if (firsterr) | 1858 | if (firsterr) |