rcutorture: Convert to hotplug state machine
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Thu, 18 Aug 2016 12:57:22 +0000 (14:57 +0200)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 22 Aug 2016 16:52:12 +0000 (09:52 -0700)
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>
kernel/rcu/rcutorture.c

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