From efefbcc50028fb025316a1a21dca5ce4fd90e881 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 4 Feb 2013 23:38:13 +0400 Subject: [PATCH] xtensa: ISS: fix timer_lock usage in rs_open This fixes the following lockdep splat: [ 66.460000] ================================= [ 66.460000] [ INFO: inconsistent lock state ] [ 66.460000] 3.9.0-rc5-00161-ga48dd49 #4 Not tainted [ 66.460000] --------------------------------- [ 66.460000] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. [ 66.460000] swapper/1 [HC0[0]:SC1[1]:HE1:SE0] takes: [ 66.460000] (timer_lock){+.?...}, at: [] rs_poll+0x12/0xdc [ 66.460000] {SOFTIRQ-ON-W} state was registered at: [ 66.460000] [] lock_acquire+0xec/0x13c [ 66.460000] [] _raw_spin_lock+0x3a/0x84 [ 66.460000] [] rs_open+0x18/0x58 [ 66.460000] [] tty_open+0x262/0x3cc [ 66.460000] [] chrdev_open+0x8c/0xe0 [ 66.460000] [] do_dentry_open$isra$16+0x10e/0x190 [ 66.460000] [] finish_open+0x39/0x48 [ 66.460000] [] do_last$isra$34+0x6c4/0x824 [ 66.460000] [] path_openat+0x66/0x310 [ 66.460000] [] do_filp_open+0x16/0x44 [ 66.460000] [] do_sys_open+0xd5/0x13c [ 66.460000] [] sys_open+0x12/0x18 [ 66.460000] [] kernel_init_freeable+0xe4/0x12c [ 66.460000] [] kernel_init+0xc/0x9c [ 66.460000] [] ret_from_kernel_thread+0x8/0xc [ 66.460000] irq event stamp: 132542 [ 66.460000] hardirqs last enabled at (132542): [] _raw_spin_unlock_irq+0x30/0x44 [ 66.460000] hardirqs last disabled at (132541): [] _raw_spin_lock_irq+0xe/0x8c [ 66.460000] softirqs last enabled at (132234): [] __do_softirq+0x216/0x2a4 [ 66.460000] softirqs last disabled at (132539): [] irq_exit+0x38/0x40 [ 66.460000] [ 66.460000] other info that might help us debug this: [ 66.460000] Possible unsafe locking scenario: [ 66.460000] [ 66.460000] CPU0 [ 66.460000] ---- [ 66.460000] lock(timer_lock); [ 66.460000] [ 66.460000] lock(timer_lock); [ 66.460000] [ 66.460000] *** DEADLOCK *** [ 66.460000] [ 66.460000] 1 lock held by swapper/1: [ 66.460000] #0: (((&serial_timer))){+.-...}, at: [] call_timer_fn+0x0/0x1f0 [ 66.460000] Stack: d7c2fac0 00000018 00000004 00000001 d7c2faa0 00000004 00000006 d7c2fa90 9003e87c d7c2fae0 d7c30000 d025a87c 00000001 0000000f 00000000 d7c2fac0 9004005d d7c2fb10 d7c30000 d7c30338 00000001 00000001 00000000 d7c30338 [ 66.460000] Call Trace: [ 66.460000] [] print_usage_bug$part$26+0x1c3/0x1c8 [ 66.460000] [] mark_lock+0x2b4/0x440 [ 66.460000] [] __lock_acquire+0x54d/0x16c4 [ 66.460000] [] lock_acquire+0xec/0x13c [ 66.460000] [] _raw_spin_lock+0x3a/0x84 [ 66.460000] [] rs_poll+0x12/0xdc [ 66.460000] [] call_timer_fn+0xbe/0x1f0 [ 66.460000] [] run_timer_softirq+0x198/0x1f4 [ 66.460000] [] __do_softirq+0x114/0x2a4 [ 66.460000] [] irq_exit+0x38/0x40 [ 66.460000] [] do_IRQ+0x44/0x48 [ 66.460000] [] do_interrupt+0x4c/0x54 [ 66.460000] [] common_exception_return+0x0/0x5c [ 66.460000] [] free_pcppages_bulk+0x254/0x308 [ 66.460000] Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/platforms/iss/console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index e869721..70cb408 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -56,13 +56,13 @@ static void rs_poll(unsigned long); static int rs_open(struct tty_struct *tty, struct file * filp) { tty->port = &serial_port; - spin_lock(&timer_lock); + spin_lock_bh(&timer_lock); if (tty->count == 1) { setup_timer(&serial_timer, rs_poll, (unsigned long)&serial_port); mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); } - spin_unlock(&timer_lock); + spin_unlock_bh(&timer_lock); return 0; } -- 2.7.4