Doc/cpu-hotplug: Specify race-free way to register CPU hotplug callbacks
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Mon, 10 Mar 2014 20:34:32 +0000 (02:04 +0530)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 20 Mar 2014 12:43:40 +0000 (13:43 +0100)
Recommend the usage of the new CPU hotplug callback registration APIs
(__register_cpu_notifier() etc), when subsystems need to also perform
initialization for already online CPUs. Provide examples of correct
and race-free ways of achieving this, and point out the kinds of code
that are error-prone.

Cc: Rob Landley <rob@landley.net>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Documentation/cpu-hotplug.txt

index be675d2..a0b005d 100644 (file)
@@ -312,12 +312,57 @@ things will happen if a notifier in path sent a BAD notify code.
 Q: I don't see my action being called for all CPUs already up and running?
 A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined.
    If you need to perform some action for each cpu already in the system, then
+   do this:
 
        for_each_online_cpu(i) {
                foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i);
                foobar_cpu_callback(&foobar_cpu_notifier, CPU_ONLINE, i);
        }
 
+   However, if you want to register a hotplug callback, as well as perform
+   some initialization for CPUs that are already online, then do this:
+
+   Version 1: (Correct)
+   ---------
+
+       cpu_notifier_register_begin();
+
+               for_each_online_cpu(i) {
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_UP_PREPARE, i);
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_ONLINE, i);
+               }
+
+       /* Note the use of the double underscored version of the API */
+       __register_cpu_notifier(&foobar_cpu_notifier);
+
+       cpu_notifier_register_done();
+
+   Note that the following code is *NOT* the right way to achieve this,
+   because it is prone to an ABBA deadlock between the cpu_add_remove_lock
+   and the cpu_hotplug.lock.
+
+   Version 2: (Wrong!)
+   ---------
+
+       get_online_cpus();
+
+               for_each_online_cpu(i) {
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_UP_PREPARE, i);
+                       foobar_cpu_callback(&foobar_cpu_notifier,
+                                           CPU_ONLINE, i);
+               }
+
+       register_cpu_notifier(&foobar_cpu_notifier);
+
+       put_online_cpus();
+
+    So always use the first version shown above when you want to register
+    callbacks as well as initialize the already online CPUs.
+
+
 Q: If i would like to develop cpu hotplug support for a new architecture,
    what do i need at a minimum?
 A: The following are what is required for CPU hotplug infrastructure to work