diff options
| -rw-r--r-- | arch/x86/Kconfig | 8 | ||||
| -rw-r--r-- | kernel/cpu.c | 20 |
2 files changed, 19 insertions, 9 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c1f9b3cf437c..5ad92419be19 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -2217,14 +2217,8 @@ config RANDOMIZE_MEMORY_PHYSICAL_PADDING | |||
| 2217 | If unsure, leave at the default value. | 2217 | If unsure, leave at the default value. |
| 2218 | 2218 | ||
| 2219 | config HOTPLUG_CPU | 2219 | config HOTPLUG_CPU |
| 2220 | bool "Support for hot-pluggable CPUs" | 2220 | def_bool y |
| 2221 | depends on SMP | 2221 | depends on SMP |
| 2222 | ---help--- | ||
| 2223 | Say Y here to allow turning CPUs off and on. CPUs can be | ||
| 2224 | controlled through /sys/devices/system/cpu. | ||
| 2225 | ( Note: power management support will enable this option | ||
| 2226 | automatically on SMP systems. ) | ||
| 2227 | Say N if you want to disable CPU hotplug. | ||
| 2228 | 2222 | ||
| 2229 | config BOOTPARAM_HOTPLUG_CPU0 | 2223 | config BOOTPARAM_HOTPLUG_CPU0 |
| 2230 | bool "Set default setting of cpu0_hotpluggable" | 2224 | bool "Set default setting of cpu0_hotpluggable" |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 025f419d16f6..6754f3ecfd94 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -564,6 +564,20 @@ static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st) | |||
| 564 | cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); | 564 | cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st) | ||
| 568 | { | ||
| 569 | if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) | ||
| 570 | return true; | ||
| 571 | /* | ||
| 572 | * When CPU hotplug is disabled, then taking the CPU down is not | ||
| 573 | * possible because takedown_cpu() and the architecture and | ||
| 574 | * subsystem specific mechanisms are not available. So the CPU | ||
| 575 | * which would be completely unplugged again needs to stay around | ||
| 576 | * in the current state. | ||
| 577 | */ | ||
| 578 | return st->state <= CPUHP_BRINGUP_CPU; | ||
| 579 | } | ||
| 580 | |||
| 567 | static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, | 581 | static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, |
| 568 | enum cpuhp_state target) | 582 | enum cpuhp_state target) |
| 569 | { | 583 | { |
| @@ -574,8 +588,10 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, | |||
| 574 | st->state++; | 588 | st->state++; |
| 575 | ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); | 589 | ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); |
| 576 | if (ret) { | 590 | if (ret) { |
| 577 | st->target = prev_state; | 591 | if (can_rollback_cpu(st)) { |
| 578 | undo_cpu_up(cpu, st); | 592 | st->target = prev_state; |
| 593 | undo_cpu_up(cpu, st); | ||
| 594 | } | ||
| 579 | break; | 595 | break; |
| 580 | } | 596 | } |
| 581 | } | 597 | } |
