From cd03083b241058a6afa0ff3f211948b07a9ea2e5 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 29 Mar 2023 17:06:50 +0900 Subject: [PATCH] bcmdhd: fix possible deadlock during dhdsdio_probe() During dhdsdio_probe, before locking rtnl_lock with dhd_register_if(), unlock _dhd_mutex_lock_ to avoid possible deadlock with dhd_open(). This fixes following possible deadlock: ====================================================== [ INFO: possible circular locking dependency detected ] 4.9.241-TIZEN-amlogic-kvim+ #2 Not tainted ------------------------------------------------------- net-config/516 is trying to acquire lock: (_dhd_mutex_lock_){+.+.+.}, at: [] dhd_open+0xd4/0x4b0 [dhd] but task is already holding lock: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x20/0x28 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (rtnl_mutex){+.+.+.}: __lock_acquire+0x1514/0x1890 lock_acquire+0xcc/0x278 mutex_lock_nested+0x88/0x3f8 rtnl_lock+0x20/0x28 wiphy_register+0x444/0x600 wl_cfg80211_attach+0x248/0x12a0 [dhd] dhd_attach+0x43c/0xc98 [dhd] dhdsdio_probe+0x16c/0x668 [dhd] bcmsdh_probe+0x12c/0x238 [dhd] bcmsdh_sdmmc_probe+0x110/0x300 [dhd] sdio_bus_probe+0xac/0x180 driver_probe_device+0x214/0x2c8 __driver_attach+0xd0/0xd8 bus_for_each_dev+0x78/0xd8 driver_attach+0x30/0x40 bus_add_driver+0x1c4/0x230 driver_register+0x6c/0x110 sdio_register_driver+0x30/0x40 bcmsdh_register_client_driver+0x1c/0x30 [dhd] bcmsdh_register+0x44/0x90 [dhd] dhd_bus_register+0x28/0x68 [dhd] dhd_wifi_platform_load+0x2bc/0x508 [dhd] dhd_wifi_platform_register_drv+0xe8/0x198 [dhd] 0xffffff80022f309c do_one_initcall+0x58/0x168 do_init_module+0x64/0x1cc load_module+0x2010/0x2678 SyS_finit_module+0xd4/0xf0 __sys_trace_return+0x0/0x4 -> #0 (_dhd_mutex_lock_){+.+.+.}: print_circular_bug+0x7c/0x2e0 __lock_acquire+0x1440/0x1890 lock_acquire+0xcc/0x278 mutex_lock_nested+0x88/0x3f8 dhd_open+0xd4/0x4b0 [dhd] __dev_open+0xe4/0x150 __dev_change_flags+0xa0/0x160 dev_change_flags+0x34/0x70 devinet_ioctl+0x76c/0x868 inet_ioctl+0x140/0x158 sock_do_ioctl+0x40/0x80 sock_ioctl+0x260/0x340 do_vfs_ioctl+0xc4/0x898 SyS_ioctl+0x8c/0xa8 __sys_trace_return+0x0/0x4 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(rtnl_mutex); lock(_dhd_mutex_lock_); lock(rtnl_mutex); lock(_dhd_mutex_lock_); *** DEADLOCK *** 1 lock held by net-config/516: #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x20/0x28 stack backtrace: CPU: 3 PID: 516 Comm: net-config Not tainted 4.9.241-TIZEN-amlogic-kvim+ #2 Hardware name: Khadas VIM3 (DT) Call trace: [] dump_backtrace+0x0/0x2a8 [] show_stack+0x24/0x30 [] dump_stack+0xe4/0x12c [] print_circular_bug+0x1d0/0x2e0 [] __lock_acquire+0x1440/0x1890 [] lock_acquire+0xcc/0x278 [] mutex_lock_nested+0x88/0x3f8 [] dhd_open+0xd4/0x4b0 [dhd] [] __dev_open+0xe4/0x150 [] __dev_change_flags+0xa0/0x160 [] dev_change_flags+0x34/0x70 [] devinet_ioctl+0x76c/0x868 [] inet_ioctl+0x140/0x158 [] sock_do_ioctl+0x40/0x80 [] sock_ioctl+0x260/0x340 [] do_vfs_ioctl+0xc4/0x898 [] SyS_ioctl+0x8c/0xa8 [] __sys_trace_return+0x0/0x4 Change-Id: I8afd6cb8e5ddec5588060715b2de6986de054fee Signed-off-by: Seung-Woo Kim --- drivers/net/wireless/bcmdhd/dhd_sdio.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c index 3d2dec9b0dca..ac638137f601 100644 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c @@ -7846,12 +7846,17 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, memcpy(bus->dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN); #endif /* GET_CUSTOM_MAC_ENABLE */ + DHD_MUTEX_UNLOCK(); + /* Ok, have the per-port tell the stack we're open for business */ if (dhd_register_if(bus->dhd, 0, TRUE) != 0) { DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__)); + DHD_MUTEX_LOCK(); goto fail; } + DHD_MUTEX_LOCK(); + #ifdef BCMHOST_XTAL_PU_TIME_MOD bcmsdh_reg_write(bus->sdh, 0x18000620, 2, 11); #ifdef BCM4330_CHIP -- 2.34.1