Commit 16e53dbf10a2d7e228709a7286310e629ede5e45

Authored by Srivatsa S. Bhat
Committed by Linus Torvalds
1 parent 77293e215e

CPU hotplug: provide a generic helper to disable/enable CPU hotplug

There are instances in the kernel where we would like to disable CPU
hotplug (from sysfs) during some important operation.  Today the freezer
code depends on this and the code to do it was kinda tailor-made for
that.

Restructure the code and make it generic enough to be useful for other
usecases too.

Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Robin Holt <holt@sgi.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Russ Anderson <rja@sgi.com>
Cc: Robin Holt <holt@sgi.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 27 additions and 32 deletions Side-by-side Diff

... ... @@ -175,6 +175,8 @@
175 175  
176 176 extern void get_online_cpus(void);
177 177 extern void put_online_cpus(void);
  178 +extern void cpu_hotplug_disable(void);
  179 +extern void cpu_hotplug_enable(void);
178 180 #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri)
179 181 #define register_hotcpu_notifier(nb) register_cpu_notifier(nb)
180 182 #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb)
... ... @@ -198,6 +200,8 @@
198 200  
199 201 #define get_online_cpus() do { } while (0)
200 202 #define put_online_cpus() do { } while (0)
  203 +#define cpu_hotplug_disable() do { } while (0)
  204 +#define cpu_hotplug_enable() do { } while (0)
201 205 #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0)
202 206 /* These aren't inline functions due to a GCC bug. */
203 207 #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
... ... @@ -133,6 +133,27 @@
133 133 mutex_unlock(&cpu_hotplug.lock);
134 134 }
135 135  
  136 +/*
  137 + * Wait for currently running CPU hotplug operations to complete (if any) and
  138 + * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects
  139 + * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the
  140 + * hotplug path before performing hotplug operations. So acquiring that lock
  141 + * guarantees mutual exclusion from any currently running hotplug operations.
  142 + */
  143 +void cpu_hotplug_disable(void)
  144 +{
  145 + cpu_maps_update_begin();
  146 + cpu_hotplug_disabled = 1;
  147 + cpu_maps_update_done();
  148 +}
  149 +
  150 +void cpu_hotplug_enable(void)
  151 +{
  152 + cpu_maps_update_begin();
  153 + cpu_hotplug_disabled = 0;
  154 + cpu_maps_update_done();
  155 +}
  156 +
136 157 #else /* #if CONFIG_HOTPLUG_CPU */
137 158 static void cpu_hotplug_begin(void) {}
138 159 static void cpu_hotplug_done(void) {}
... ... @@ -541,36 +562,6 @@
541 562 core_initcall(alloc_frozen_cpus);
542 563  
543 564 /*
544   - * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU
545   - * hotplug when tasks are about to be frozen. Also, don't allow the freezer
546   - * to continue until any currently running CPU hotplug operation gets
547   - * completed.
548   - * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the
549   - * 'cpu_add_remove_lock'. And this same lock is also taken by the regular
550   - * CPU hotplug path and released only after it is complete. Thus, we
551   - * (and hence the freezer) will block here until any currently running CPU
552   - * hotplug operation gets completed.
553   - */
554   -void cpu_hotplug_disable_before_freeze(void)
555   -{
556   - cpu_maps_update_begin();
557   - cpu_hotplug_disabled = 1;
558   - cpu_maps_update_done();
559   -}
560   -
561   -
562   -/*
563   - * When tasks have been thawed, re-enable regular CPU hotplug (which had been
564   - * disabled while beginning to freeze tasks).
565   - */
566   -void cpu_hotplug_enable_after_thaw(void)
567   -{
568   - cpu_maps_update_begin();
569   - cpu_hotplug_disabled = 0;
570   - cpu_maps_update_done();
571   -}
572   -
573   -/*
574 565 * When callbacks for CPU hotplug notifications are being executed, we must
575 566 * ensure that the state of the system with respect to the tasks being frozen
576 567 * or not, as reported by the notification, remains unchanged *throughout the
577 568  
... ... @@ -589,12 +580,12 @@
589 580  
590 581 case PM_SUSPEND_PREPARE:
591 582 case PM_HIBERNATION_PREPARE:
592   - cpu_hotplug_disable_before_freeze();
  583 + cpu_hotplug_disable();
593 584 break;
594 585  
595 586 case PM_POST_SUSPEND:
596 587 case PM_POST_HIBERNATION:
597   - cpu_hotplug_enable_after_thaw();
  588 + cpu_hotplug_enable();
598 589 break;
599 590  
600 591 default: