diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 11 | 
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index aa7fe85ad62e..0097acec1c71 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -607,15 +607,15 @@ static void cpuhp_thread_fun(unsigned int cpu)  	bool bringup = st->bringup;  	enum cpuhp_state state; +	if (WARN_ON_ONCE(!st->should_run)) +		return; +  	/*  	 * ACQUIRE for the cpuhp_should_run() load of ->should_run. Ensures  	 * that if we see ->should_run we also see the rest of the state.  	 */  	smp_mb(); -	if (WARN_ON_ONCE(!st->should_run)) -		return; -  	cpuhp_lock_acquire(bringup);  	if (st->single) { @@ -916,7 +916,8 @@ static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,  		ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL);  		if (ret) {  			st->target = prev_state; -			undo_cpu_down(cpu, st); +			if (st->state < prev_state) +				undo_cpu_down(cpu, st);  			break;  		}  	} @@ -969,7 +970,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,  	 * to do the further cleanups.  	 */  	ret = cpuhp_down_callbacks(cpu, st, target); -	if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) { +	if (ret && st->state == CPUHP_TEARDOWN_CPU && st->state < prev_state) {  		cpuhp_reset_state(st, prev_state);  		__cpuhp_kick_ap(st);  	}  | 
