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>
This commit is contained in:
Sebastian Andrzej Siewior 2016-08-18 14:57:22 +02:00 committed by Paul E. McKenney
parent 0c6d4576c4
commit 0ffd374b22

View File

@ -1362,12 +1362,12 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, const char *tag)
onoff_interval, onoff_holdoff); onoff_interval, onoff_holdoff);
} }
static void rcutorture_booster_cleanup(int cpu) static int rcutorture_booster_cleanup(unsigned int cpu)
{ {
struct task_struct *t; struct task_struct *t;
if (boost_tasks[cpu] == NULL) if (boost_tasks[cpu] == NULL)
return; return 0;
mutex_lock(&boost_mutex); mutex_lock(&boost_mutex);
t = boost_tasks[cpu]; t = boost_tasks[cpu];
boost_tasks[cpu] = NULL; boost_tasks[cpu] = NULL;
@ -1375,9 +1375,10 @@ static void rcutorture_booster_cleanup(int cpu)
/* This must be outside of the mutex, otherwise deadlock! */ /* This must be outside of the mutex, otherwise deadlock! */
torture_stop_kthread(rcu_torture_boost, t); torture_stop_kthread(rcu_torture_boost, t);
return 0;
} }
static int rcutorture_booster_init(int cpu) static int rcutorture_booster_init(unsigned int cpu)
{ {
int retval; int retval;
@ -1577,28 +1578,7 @@ static void rcu_torture_barrier_cleanup(void)
} }
} }
static int rcutorture_cpu_notify(struct notifier_block *self, static enum cpuhp_state rcutor_hp;
unsigned long action, void *hcpu)
{
long cpu = (long)hcpu;
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE:
case CPU_DOWN_FAILED:
(void)rcutorture_booster_init(cpu);
break;
case CPU_DOWN_PREPARE:
rcutorture_booster_cleanup(cpu);
break;
default:
break;
}
return NOTIFY_OK;
}
static struct notifier_block rcutorture_cpu_nb = {
.notifier_call = rcutorture_cpu_notify,
};
static void static void
rcu_torture_cleanup(void) rcu_torture_cleanup(void)
@ -1638,11 +1618,8 @@ rcu_torture_cleanup(void)
for (i = 0; i < ncbflooders; i++) for (i = 0; i < ncbflooders; i++)
torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]); torture_stop_kthread(rcu_torture_cbflood, cbflood_task[i]);
if ((test_boost == 1 && cur_ops->can_boost) || if ((test_boost == 1 && cur_ops->can_boost) ||
test_boost == 2) { test_boost == 2)
unregister_cpu_notifier(&rcutorture_cpu_nb); cpuhp_remove_state(rcutor_hp);
for_each_possible_cpu(i)
rcutorture_booster_cleanup(i);
}
/* /*
* Wait for all RCU callbacks to fire, then do flavor-specific * Wait for all RCU callbacks to fire, then do flavor-specific
@ -1869,14 +1846,13 @@ rcu_torture_init(void)
test_boost == 2) { test_boost == 2) {
boost_starttime = jiffies + test_boost_interval * HZ; boost_starttime = jiffies + test_boost_interval * HZ;
register_cpu_notifier(&rcutorture_cpu_nb);
for_each_possible_cpu(i) { firsterr = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "RCU_TORTURE",
if (cpu_is_offline(i)) rcutorture_booster_init,
continue; /* Heuristic: CPU can go offline. */ rcutorture_booster_cleanup);
firsterr = rcutorture_booster_init(i); if (firsterr < 0)
if (firsterr) goto unwind;
goto unwind; rcutor_hp = firsterr;
}
} }
firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup); firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
if (firsterr) if (firsterr)