Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Srivatsa S. Bhat and committed by
Linus Torvalds
16e53dbf 77293e21

+27 -32
+4
include/linux/cpu.h
··· 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) ··· 200 198 201 199 #define get_online_cpus() do { } while (0) 202 200 #define put_online_cpus() do { } while (0) 201 + #define cpu_hotplug_disable() do { } while (0) 202 + #define cpu_hotplug_enable() do { } while (0) 203 203 #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) 204 204 /* These aren't inline functions due to a GCC bug. */ 205 205 #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
+23 -32
kernel/cpu.c
··· 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) {} ··· 562 541 core_initcall(alloc_frozen_cpus); 563 542 564 543 /* 565 - * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU 566 - * hotplug when tasks are about to be frozen. Also, don't allow the freezer 567 - * to continue until any currently running CPU hotplug operation gets 568 - * completed. 569 - * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the 570 - * 'cpu_add_remove_lock'. And this same lock is also taken by the regular 571 - * CPU hotplug path and released only after it is complete. Thus, we 572 - * (and hence the freezer) will block here until any currently running CPU 573 - * hotplug operation gets completed. 574 - */ 575 - void cpu_hotplug_disable_before_freeze(void) 576 - { 577 - cpu_maps_update_begin(); 578 - cpu_hotplug_disabled = 1; 579 - cpu_maps_update_done(); 580 - } 581 - 582 - 583 - /* 584 - * When tasks have been thawed, re-enable regular CPU hotplug (which had been 585 - * disabled while beginning to freeze tasks). 586 - */ 587 - void cpu_hotplug_enable_after_thaw(void) 588 - { 589 - cpu_maps_update_begin(); 590 - cpu_hotplug_disabled = 0; 591 - cpu_maps_update_done(); 592 - } 593 - 594 - /* 595 544 * When callbacks for CPU hotplug notifications are being executed, we must 596 545 * ensure that the state of the system with respect to the tasks being frozen 597 546 * or not, as reported by the notification, remains unchanged *throughout the ··· 580 589 581 590 case PM_SUSPEND_PREPARE: 582 591 case PM_HIBERNATION_PREPARE: 583 - cpu_hotplug_disable_before_freeze(); 592 + cpu_hotplug_disable(); 584 593 break; 585 594 586 595 case PM_POST_SUSPEND: 587 596 case PM_POST_HIBERNATION: 588 - cpu_hotplug_enable_after_thaw(); 597 + cpu_hotplug_enable(); 589 598 break; 590 599 591 600 default: