bcmdhd: fix possible deadlock during dhdsdio_probe() 83/290583/2
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 29 Mar 2023 08:06:50 +0000 (17:06 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Fri, 31 Mar 2023 03:24:06 +0000 (12:24 +0900)
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: [<ffffff80021b2f44>] dhd_open+0xd4/0x4b0 [dhd]

   but task is already holding lock:
    (rtnl_mutex){+.+.+.}, at: [<ffffff8009db8028>] 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: [<ffffff8009db8028>] 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:
   [<ffffff800908baa8>] dump_backtrace+0x0/0x2a8
   [<ffffff800908bdd4>] show_stack+0x24/0x30
   [<ffffff80095b92b0>] dump_stack+0xe4/0x12c
   [<ffffff8009121bd0>] print_circular_bug+0x1d0/0x2e0
   [<ffffff8009124898>] __lock_acquire+0x1440/0x1890
   [<ffffff800912510c>] lock_acquire+0xcc/0x278
   [<ffffff800a0eb0b8>] mutex_lock_nested+0x88/0x3f8
   [<ffffff80021b2f44>] dhd_open+0xd4/0x4b0 [dhd]
   [<ffffff8009da6fd4>] __dev_open+0xe4/0x150
   [<ffffff8009da7320>] __dev_change_flags+0xa0/0x160
   [<ffffff8009da7414>] dev_change_flags+0x34/0x70
   [<ffffff8009e8e4e4>] devinet_ioctl+0x76c/0x868
   [<ffffff8009e91280>] inet_ioctl+0x140/0x158
   [<ffffff8009d78110>] sock_do_ioctl+0x40/0x80
   [<ffffff8009d79490>] sock_ioctl+0x260/0x340
   [<ffffff80092a349c>] do_vfs_ioctl+0xc4/0x898
   [<ffffff80092a3cfc>] SyS_ioctl+0x8c/0xa8
   [<ffffff8009083a1c>] __sys_trace_return+0x0/0x4

Change-Id: I8afd6cb8e5ddec5588060715b2de6986de054fee
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
drivers/net/wireless/bcmdhd/dhd_sdio.c

index 3d2dec9..ac63813 100644 (file)
@@ -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