If the work item is running, the cancel_work_sync in ar5523_stop will not return until work item is finished. If we hold mutex_lock and use cancel_work_sync to wait the work item to finish, the work item such as ar5523_tx_wd_work and ar5523_tx_work also require mutex_lock. As a result, the ar5523_stop will be blocked forever. One of the race conditions is shown below: (Thread 1) | (Thread 2) ar5523_stop | mutex_lock(&ar->mutex) | ar5523_tx_wd_work | mutex_lock(&ar->mutex) cancel_work_sync | ... This patch moves cancel_work_sync out of mutex_lock in order to mitigate deadlock bugs. Fixes: b7d572e1871d ("ar5523: Add new driver") Signed-off-by: Duoming Zhou <duoming@xxxxxxxxxx> --- drivers/net/wireless/ath/ar5523/ar5523.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 9cabd342d15..99d6b13ffcf 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1071,8 +1071,10 @@ static void ar5523_stop(struct ieee80211_hw *hw) ar5523_cmd_write(ar, WDCMSG_TARGET_STOP, NULL, 0, 0); del_timer_sync(&ar->tx_wd_timer); + mutex_unlock(&ar->mutex); cancel_work_sync(&ar->tx_wd_work); cancel_work_sync(&ar->rx_refill_work); + mutex_lock(&ar->mutex); ar5523_cancel_rx_bufs(ar); mutex_unlock(&ar->mutex); } -- 2.17.1