From 3617d0109265dd2f070cc4b358b7588ddb1af343 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 6 Feb 2020 15:17:16 +0000 Subject: [PATCH] s390: Fix unmatched preempt_disable() on exit exit_thread_runtime_instr() may return with preemption disabled, leading to the following lockdep splat: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:586 in_atomic(): 1, irqs_disabled(): 0, pid: 565, name: kworker/u2:0 no locks held by kworker/u2:0/565. CPU: 0 PID: 565 Comm: kworker/u2:0 Not tainted 3.16.81-00145-gafe1c874fa44 #1 00000000025dbbd8 00000000025dbbe8 0000000000000002 0000000000000000 00000000025dbc78 00000000025dbbf0 00000000025dbbf0 000000000098c55c 0000000000000000 00000000025d05b8 00000000025d1590 0000000000000000 0000000000000000 000000000000000c 00000000025dbbd8 0000000000000070 00000000009b7220 000000000098c55c 00000000025dbbd8 00000000025dbc20 Call Trace: ([<000000000098c4ce>] show_trace+0xb6/0xd8) [<000000000098c592>] show_stack+0xa2/0xd8 [<0000000000992c04>] dump_stack+0xc4/0x118 [<0000000000191e20>] __might_sleep+0x230/0x238 [<000000000099fbb0>] mutex_lock_nested+0x48/0x3d8 [<000000000025e33e>] perf_event_exit_task+0x36/0x398 [<0000000000158536>] do_exit+0x3ae/0xca0 [<0000000000175826>] ____call_usermodehelper+0x136/0x148 [<00000000009a550a>] kernel_thread_starter+0x6/0xc [<00000000009a5504>] kernel_thread_starter+0x0/0xc This was fixed by commit 8d9047f8b967 "s390/runtime instrumentation: simplify task exit handling" upstream, but that won't apply here. Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Signed-off-by: Ben Hutchings --- arch/s390/kernel/runtime_instr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index ddbec1054f75d..9808fe741def1 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -53,9 +53,9 @@ void exit_thread_runtime_instr(void) { struct task_struct *task = current; - preempt_disable(); if (!task->thread.ri_cb) return; + preempt_disable(); disable_runtime_instr(); kfree(task->thread.ri_cb); task->thread.ri_signum = 0;