]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/xtensa-smp-fix-ccount_timer_shutdown.patch
Linux 3.18.137
[thirdparty/kernel/stable-queue.git] / queue-4.4 / xtensa-smp-fix-ccount_timer_shutdown.patch
1 From 04ea0be0a3ed8372dbc41be1b5f119a38792801d Mon Sep 17 00:00:00 2001
2 From: Max Filippov <jcmvbkbc@gmail.com>
3 Date: Mon, 29 Jan 2018 09:09:41 -0800
4 Subject: xtensa: SMP: fix ccount_timer_shutdown
5
6 [ Upstream commit 4fe8713b873fc881284722ce4ac47995de7cf62c ]
7
8 ccount_timer_shutdown is called from the atomic context in the
9 secondary_start_kernel, resulting in the following BUG:
10
11 BUG: sleeping function called from invalid context
12 in_atomic(): 1, irqs_disabled(): 1, pid: 0, name: swapper/1
13 Preemption disabled at:
14 secondary_start_kernel+0xa1/0x130
15 Call Trace:
16 ___might_sleep+0xe7/0xfc
17 __might_sleep+0x41/0x44
18 synchronize_irq+0x24/0x64
19 disable_irq+0x11/0x14
20 ccount_timer_shutdown+0x12/0x20
21 clockevents_switch_state+0x82/0xb4
22 clockevents_exchange_device+0x54/0x60
23 tick_check_new_device+0x46/0x70
24 clockevents_register_device+0x8c/0xc8
25 clockevents_config_and_register+0x1d/0x2c
26 local_timer_setup+0x75/0x7c
27 secondary_start_kernel+0xb4/0x130
28 should_never_return+0x32/0x35
29
30 Use disable_irq_nosync instead of disable_irq to avoid it.
31 This is safe because the ccount timer IRQ is per-CPU, and once IRQ is
32 masked the ISR will not be called.
33
34 Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
35 Signed-off-by: Sasha Levin <sashal@kernel.org>
36 ---
37 arch/xtensa/kernel/time.c | 2 +-
38 1 file changed, 1 insertion(+), 1 deletion(-)
39
40 diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
41 index b9ad9feadc2d..a992cb6a47db 100644
42 --- a/arch/xtensa/kernel/time.c
43 +++ b/arch/xtensa/kernel/time.c
44 @@ -87,7 +87,7 @@ static int ccount_timer_shutdown(struct clock_event_device *evt)
45 container_of(evt, struct ccount_timer, evt);
46
47 if (timer->irq_enabled) {
48 - disable_irq(evt->irq);
49 + disable_irq_nosync(evt->irq);
50 timer->irq_enabled = 0;
51 }
52 return 0;
53 --
54 2.19.1
55