From 39ba832e8349acdc0661903012dd4a01f1ac9b52 Mon Sep 17 00:00:00 2001 From: William Wu Date: Wed, 7 Jun 2017 21:13:25 +0800 Subject: [PATCH] phy: rockchip-inno-usb2: fix possibe deadlock The commit 611ec35fa148 ("phy: rockchip-inno-usb2: fix some race conditions") use mutex lock to protect charger detect work, but it will cause the following possible deadlock. [ INFO: possible circular locking dependency detected ] 4.4.66 #563 Not tainted ------------------------------------------------------- kworker/3:1/145 is trying to acquire lock: (&rport->mutex){+.+...}, at: [] rockchip_chg_detect_work+0x6c/0x3d0 but task is already holding lock: ((&(&rport->chg_work)->work)){+.+...}, at: [] process_one_work+0x1c4/0x6ac which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 ((&(&rport->chg_work)->work)){+.+...}: [] __lock_acquire+0x15c0/0x195c [] lock_acquire+0x190/0x250 [] flush_work+0x4c/0x274 [] __cancel_work_timer+0x130/0x1c0 [] cancel_delayed_work_sync+0x10/0x18 [] rockchip_usb2phy_exit+0x54/0x6c [] phy_exit+0x64/0xb4 [] dwc3_core_exit+0x44/0x98 [] dwc3_suspend_common+0x4c/0x5c [] dwc3_runtime_suspend+0x38/0x5c [] pm_generic_runtime_suspend+0x28/0x38 [] __rpm_callback+0x40/0x74 [] rpm_callback+0x5c/0x80 [] rpm_suspend+0x31c/0x688 [] __pm_runtime_suspend+0x58/0xa4 [] dwc3_rockchip_probe+0x3f8/0x574 [] platform_drv_probe+0x58/0xa4 [] driver_probe_device+0x118/0x2b0 [] __device_attach_driver+0x88/0x98 [] bus_for_each_drv+0x7c/0xac [] __device_attach+0xa8/0x128 [] device_initial_probe+0x10/0x18 [] bus_probe_device+0x2c/0x90 [] deferred_probe_work_func+0x78/0xa8 [] process_one_work+0x338/0x6ac [] worker_thread+0x300/0x428 [] kthread+0x104/0x10c [] ret_from_fork+0x10/0x50 -> #0 (&rport->mutex){+.+...}: [] print_circular_bug+0x64/0x2c4 [] __lock_acquire+0x128c/0x195c [] lock_acquire+0x190/0x250 [] mutex_lock_nested+0x80/0x3d0 [] rockchip_chg_detect_work+0x6c/0x3d0 [] process_one_work+0x338/0x6ac [] worker_thread+0x300/0x428 [] kthread+0x104/0x10c [] ret_from_fork+0x10/0x50 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock((&(&rport->chg_work)->work)); lock(&rport->mutex); lock((&(&rport->chg_work)->work)); lock(&rport->mutex); *** DEADLOCK *** 2 locks held by kworker/3:1/145: stack backtrace: CPU: 3 PID: 145 Comm: kworker/3:1 Not tainted 4.4.66 #563 Hardware name: Rockchip RK3399 Evaluation Board v3 (Android) (DT) Workqueue: events rockchip_chg_detect_work Call trace: [] dump_backtrace+0x0/0x1c8 [] show_stack+0x14/0x1c [] dump_stack+0xb0/0xec [] print_circular_bug+0x2a8/0x2c4 [] __lock_acquire+0x128c/0x195c [] lock_acquire+0x190/0x250 [] mutex_lock_nested+0x80/0x3d0 [] rockchip_chg_detect_work+0x6c/0x3d0 [] process_one_work+0x338/0x6ac [] worker_thread+0x300/0x428 [] kthread+0x104/0x10c [] ret_from_fork+0x10/0x50 Change-Id: I4289afb05d334bf79000090f9071cf428817a583 Signed-off-by: William Wu --- drivers/phy/phy-rockchip-inno-usb2.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c index 8c930fcac0cd..6a04a4fb302f 100644 --- a/drivers/phy/phy-rockchip-inno-usb2.c +++ b/drivers/phy/phy-rockchip-inno-usb2.c @@ -582,18 +582,9 @@ static int rockchip_usb2phy_exit(struct phy *phy) { struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); - mutex_lock(&rport->mutex); - - if (rport->port_id == USB2PHY_PORT_OTG && - rport->mode != USB_DR_MODE_HOST && - rport->mode != USB_DR_MODE_UNKNOWN && - !rport->vbus_always_on) - cancel_delayed_work_sync(&rport->chg_work); - else if (rport->port_id == USB2PHY_PORT_HOST) + if (rport->port_id == USB2PHY_PORT_HOST) cancel_delayed_work_sync(&rport->sm_work); - mutex_unlock(&rport->mutex); - return 0; } -- 2.34.1