diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 20 | 
1 files changed, 18 insertions, 2 deletions
| 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)  		cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL);  } +static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st) +{ +	if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) +		return true; +	/* +	 * When CPU hotplug is disabled, then taking the CPU down is not +	 * possible because takedown_cpu() and the architecture and +	 * subsystem specific mechanisms are not available. So the CPU +	 * which would be completely unplugged again needs to stay around +	 * in the current state. +	 */ +	return st->state <= CPUHP_BRINGUP_CPU; +} +  static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,  			      enum cpuhp_state target)  { @@ -574,8 +588,10 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,  		st->state++;  		ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL);  		if (ret) { -			st->target = prev_state; -			undo_cpu_up(cpu, st); +			if (can_rollback_cpu(st)) { +				st->target = prev_state; +				undo_cpu_up(cpu, st); +			}  			break;  		}  	} |