diff options
Diffstat (limited to 'kernel/stop_machine.c')
| -rw-r--r-- | kernel/stop_machine.c | 15 | 
1 files changed, 5 insertions, 10 deletions
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 7ff7acee2c76..61101193967e 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -435,7 +435,6 @@ static void cpu_stopper_thread(unsigned int cpu)  {  	struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);  	struct cpu_stop_work *work; -	int ret;  repeat:  	work = NULL; @@ -451,23 +450,19 @@ repeat:  		cpu_stop_fn_t fn = work->fn;  		void *arg = work->arg;  		struct cpu_stop_done *done = work->done; -		char ksym_buf[KSYM_NAME_LEN] __maybe_unused; +		int ret; -		/* cpu stop callbacks are not allowed to sleep */ -		preempt_disable(); +		/* cpu stop callbacks must not sleep, make in_atomic() == T */ +		preempt_count_inc();  		ret = fn(arg);  		if (done) {  			if (ret)  				done->ret = ret;  			cpu_stop_signal_done(done);  		} -		/* restore preemption and check it's still balanced */ -		preempt_enable(); +		preempt_count_dec();  		WARN_ONCE(preempt_count(), -			  "cpu_stop: %s(%p) leaked preempt count\n", -			  kallsyms_lookup((unsigned long)fn, NULL, NULL, NULL, -					  ksym_buf), arg); - +			  "cpu_stop: %pf(%p) leaked preempt count\n", fn, arg);  		goto repeat;  	}  }  |