]> git.baikalelectronics.ru Git - kernel.git/commitdiff
rtw88: avoid holding mutex for cancel_delayed_work_sync()
authorYan-Hsuan Chuang <yhchuang@realtek.com>
Wed, 5 Feb 2020 07:08:56 +0000 (15:08 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 12 Feb 2020 16:18:28 +0000 (18:18 +0200)
Driver could possibly be dead-locked while canceling works with
*_sync() with mutex lock held. Those cancel_delayed_work_sync()
functions will wait until the work is done, but if we hold the
lock, they will never acquire the lock.

To prevent this, simply release the lock and acquire again after
the works have been canceled. And to avoid the works being queued
again, check if the device is at RTW_FLAG_RUNNING state, otherwise
just return and do nothing.

Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/realtek/rtw88/coex.c
drivers/net/wireless/realtek/rtw88/fw.c
drivers/net/wireless/realtek/rtw88/main.c

index 4dfb2ec395eedadd6873d28e0ff82cd9ca9d61d7..f91dc21a8bf1cdeddcb9c74666409b0c074aa9f6 100644 (file)
@@ -1904,6 +1904,9 @@ static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason)
 
        lockdep_assert_held(&rtwdev->mutex);
 
+       if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags))
+               return;
+
        coex_dm->reason = reason;
 
        /* update wifi_link_info_ext variable */
index b765b26b6926e55892485b42da639a4349591d6d..b36928470fc046395cd4d511c8f91e8971e2b6a3 100644 (file)
@@ -136,6 +136,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
 
        mutex_lock(&rtwdev->mutex);
 
+       if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags))
+               goto unlock;
+
        switch (c2h->id) {
        case C2H_BT_INFO:
                rtw_coex_bt_info_notify(rtwdev, c2h->payload, len);
@@ -153,6 +156,7 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
                break;
        }
 
+unlock:
        mutex_unlock(&rtwdev->mutex);
 }
 
index 2845d2838f7bc48dfa2b4d2c758cc0de56edaa35..edecc7d7ea565f45839e8720897f6eb9b076927d 100644 (file)
@@ -909,11 +909,16 @@ void rtw_core_stop(struct rtw_dev *rtwdev)
        clear_bit(RTW_FLAG_RUNNING, rtwdev->flags);
        clear_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags);
 
+       mutex_unlock(&rtwdev->mutex);
+
+       cancel_work_sync(&rtwdev->c2h_work);
        cancel_delayed_work_sync(&rtwdev->watch_dog_work);
        cancel_delayed_work_sync(&coex->bt_relink_work);
        cancel_delayed_work_sync(&coex->bt_reenable_work);
        cancel_delayed_work_sync(&coex->defreeze_work);
 
+       mutex_lock(&rtwdev->mutex);
+
        rtw_power_off(rtwdev);
 }