From f56978457cd094f18fbb2d49a883921737d60b14 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 31 Jan 2012 14:36:20 +0530 Subject: tty: serial: amba-pl011: fix cancel_delayed_work() usage PL011 calls del_timer_sync() (via cancel_delayed_work()) from atomic context. Fix it. ====================================================== [ INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected ] 3.0.8+ #1188 ------------------------------------------------------ kworker/u:0/5 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: (&(&uap->clk_off_work)->timer){+.-...}, at: [] del_timer_sync+0x0/0xc8 and this task is already holding: (&port_lock_key){-.-...}, at: [] pl011_clock_on+0x80/0xc4 which would create a new lock dependency: (&port_lock_key){-.-...} -> (&(&uap->clk_off_work)->timer){+.-...} but this new dependency connects a HARDIRQ-irq-safe lock: (&port_lock_key){-.-...} ... which became HARDIRQ-irq-safe at: [] mark_irqflags+0x68/0x170 [] __lock_acquire+0x598/0x788 [] lock_acquire+0x10c/0x130 [] _raw_spin_lock_irqsave+0x5c/0x98 [] pl011_int+0x10/0x128 [] handle_irq_event_percpu+0x98/0x1f4 [] handle_irq_event+0x3c/0x5c [] handle_fasteoi_irq+0xc8/0x100 [] generic_handle_irq+0x28/0x30 [] asm_do_IRQ+0x78/0xb8 [] __irq_svc+0x50/0xf4 [] enter_sleep+0x550/0x608 [] cpuidle_idle_call+0x1c4/0x33c [] cpu_idle+0xa4/0x10c [] start_kernel+0x228/0x27c [<00008040>] 0x8040 to a HARDIRQ-irq-unsafe lock: (&(&uap->clk_off_work)->timer){+.-...} ... which became HARDIRQ-irq-unsafe at: ... [] mark_irqflags+0xec/0x170 [] __lock_acquire+0x598/0x788 [] lock_acquire+0x10c/0x130 [] call_timer_fn+0x68/0x1e4 [] run_timer_softirq+0x1c8/0x224 [] __do_softirq+0x110/0x23c [] irq_exit+0x5c/0xc0 [] do_local_timer+0x50/0x80 [] __irq_svc+0x50/0xf4 [] __mutex_unlock_slowpath+0x150/0x17c [] sysfs_addrm_finish+0x10/0x74 [] sysfs_add_file_mode+0x70/0xb0 [] create_files+0x7c/0xb4 [] internal_create_group+0xb8/0x118 [] device_add_groups+0x1c/0x70 [] device_add_attrs+0x50/0xa8 [] device_add+0x110/0x2b4 [] hci_register_sysfs+0x54/0x114 [] hci_register_dev+0x378/0x4d8 [] register_bluetooth+0xb4/0x124 [] probe_common+0x7c/0xcc [] btcg2900_evt_probe+0x38/0x6c [] platform_drv_probe+0x18/0x1c [] really_probe+0x98/0x148 [] driver_probe_device+0x48/0x60 [] bus_for_each_drv+0x44/0x74 [] device_attach+0x78/0xa4 [] bus_probe_device+0x24/0x40 [] device_add+0x174/0x2b4 [] platform_device_add+0x104/0x160 [] mfd_add_device+0x194/0x1d4 [] mfd_add_devices+0x70/0xbc [] work_power_off_chip+0x11c/0x1c8 [] process_one_work+0x2ac/0x4c8 [] worker_thread+0x144/0x234 [] kthread+0x80/0x88 [] kernel_thread_exit+0x0/0x8 other info that might help us debug this: Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&(&uap->clk_off_work)->timer); local_irq_disable(); lock(&port_lock_key); lock(&(&uap->clk_off_work)->timer); lock(&port_lock_key); *** DEADLOCK *** Change-Id: I55d565d484baaee2dc76f258a5066aacbb6e6dee Signed-off-by: Rabin Vincent ST-Ericsson ID: 413918 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I1a45effb0afeb4344f03ca500a5b0767bd760ec3 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/47174 Reviewed-by: QABUILD Reviewed-by: Shreshtha Kumar SAHU Reviewed-by: Rabin VINCENT Tested-by: Rabin VINCENT --- drivers/tty/serial/amba-pl011.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index bed430df99e..d356b940382 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1306,7 +1306,7 @@ static void pl011_clock_on(struct uart_port *port) } /* fallthrough */ case PL011_CLK_REQUEST_OFF: - cancel_delayed_work(&uap->clk_off_work); + __cancel_delayed_work(&uap->clk_off_work); uap->clk_state = PL011_CLK_ON; break; default: @@ -1321,7 +1321,7 @@ static void pl011_clock_check(struct uart_amba_port *uap) /* Reshedule work during off request */ if (uap->clk_state == PL011_CLK_REQUEST_OFF) /* New TX - restart work */ - if (cancel_delayed_work(&uap->clk_off_work)) + if (__cancel_delayed_work(&uap->clk_off_work)) schedule_delayed_work(&uap->clk_off_work, uap->clk_off_delay); } -- cgit v1.2.3