From feb85c154f0a457e17c8b74e9eb2938207a76090 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Wed, 29 Apr 2015 19:07:35 +0530 Subject: drivers: w1: tegra_w1: Fix race condition on high CPU load On Tegra3 at high CPU load, for example while running stress, reading data from one wire results in the following stack trace: [ 58.436052] [] (__raw_spin_lock_irqsave+0x3c/0xac) from [] (_raw_spin_lock_irqsave+0x18/0x1c) [ 58.446322] [] (_raw_spin_lock_irqsave+0x18/0x1c) from [] (complete+0x28/0x64) [ 58.455276] [] (complete+0x28/0x64) from [] (tegra_w1_irq+0x74/0xb4) [ 58.463376] [] (tegra_w1_irq+0x74/0xb4) from [] (handle_irq_event_percpu+0x9c/0x278) [ 58.472847] [] (handle_irq_event_percpu+0x9c/0x278) from [] (handle_irq_event+0x4c/0x6c) [ 58.482666] [] (handle_irq_event+0x4c/0x6c) from [] (handle_fasteoi_irq+0xe0/0x118) [ 58.492048] [] (handle_fasteoi_irq+0xe0/0x118) from [] (generic_handle_irq+0x30/0x40) [ 58.501616] [] (generic_handle_irq+0x30/0x40) from [] (handle_IRQ+0x88/0xc8) [ 58.510393] [] (handle_IRQ+0x88/0xc8) from [] (asm_do_IRQ+0x18/0x1c) [ 58.518475] [] (asm_do_IRQ+0x18/0x1c) from [] (__irq_usr+0x38/0xc0) [ 58.526464] Exception stack(0xe51a3fb0 to 0xe51a3ff8) [ 58.531506] 3fa0: 00000000 bea29b04 4030b1b0 4030b4c8 [ 58.539673] 3fc0: 4030b22c 4fd2f305 0000d770 0000d6b0 00000000 00000001 0000000d 00000145 [ 58.547839] 3fe0: 193c62ce bea29af4 4030b22c 4020beb4 600b0010 ffffffff [ 58.554445] Code: e5843004 e10f0000 f10c0080 e3a02001 (e1953f9f) [ 58.560539] ---[ end trace fb2fc83ceb8e95c1 ]--- [ 58.565154] Kernel panic - not syncing: Fatal exception in interrupt [ 58.571520] [] (unwind_backtrace+0x0/0xec) from [] (dump_stack+0x20/0x24) [ 58.580039] [] (dump_stack+0x20/0x24) from [] (panic+0x7c/0x1ac) [ 58.587783] [] (panic+0x7c/0x1ac) from [] (die+0x280/0x2e8) [ 58.595087] [] (die+0x280/0x2e8) from [] (__do_kernel_fault.part.3+0x64/0x84) [ 58.603952] [] (__do_kernel_fault.part.3+0x64/0x84) from [] (do_page_fault+0x204/0x21c) [ 58.613681] [] (do_page_fault+0x204/0x21c) from [] (do_DataAbort+0x44/0xa8) [ 58.622369] [] (do_DataAbort+0x44/0xa8) from [] (__dabt_svc+0x38/0x60) This seems to be generated due a possible race condition between the on stack kernel completion being set to NULL in tegra_w1_touch_bit, while a possible spurious IRQ calling this completion in the IRQ handler. This is a temporary bandaid and the ideal solution would be to find why this affects the Tegra3 and not Tegra2. Signed-off-by: Sanchayan Maity Signed-off-by: Stefan Agner --- drivers/w1/masters/tegra_w1.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/w1/masters/tegra_w1.c b/drivers/w1/masters/tegra_w1.c index 9443c4b1dbc6..85eefd4d7eb5 100644 --- a/drivers/w1/masters/tegra_w1.c +++ b/drivers/w1/masters/tegra_w1.c @@ -290,7 +290,9 @@ static u8 tegra_w1_touch_bit(void *data, u8 bit) done: w1_imask(dev, 0); + spin_lock(&dev->spinlock); dev->transfer_completion = NULL; + spin_unlock(&dev->spinlock); clk_disable(dev->clk); mutex_unlock(&dev->mutex); return return_bit; @@ -334,7 +336,9 @@ done: } w1_imask(dev, 0); + spin_lock(&dev->spinlock); dev->transfer_completion = NULL; + spin_unlock(&dev->spinlock); clk_disable(dev->clk); mutex_unlock(&dev->mutex); return presence; -- cgit v1.2.3