Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ar9170: fix hang on stop

This patch fixes a locking problem which freezes the network core.

The deadlock goes as follows:
- ar9170_op_stop - is called
1. change the state to IDLE
2. > take the MUTEX <
3. cancel_SYNC all pending work, which means
"block until a work_struct's callback has terminated"
=> if filter_config_work was queued it tries to get the MUTEX,
before checking the device state...

Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Christian Lamparter and committed by
John W. Linville
32c1628f 807e3739

+4 -3
+4 -3
drivers/net/wireless/ar9170/main.c
··· 742 742 if (IS_STARTED(ar)) 743 743 ar->state = AR9170_IDLE; 744 744 745 - mutex_lock(&ar->mutex); 745 + flush_workqueue(ar->hw->workqueue); 746 746 747 + mutex_lock(&ar->mutex); 747 748 cancel_delayed_work_sync(&ar->tx_status_janitor); 748 749 cancel_work_sync(&ar->filter_config_work); 749 750 cancel_work_sync(&ar->beacon_work); ··· 1124 1123 filter_config_work); 1125 1124 int err; 1126 1125 1127 - mutex_lock(&ar->mutex); 1128 1126 if (unlikely(!IS_STARTED(ar))) 1129 - goto unlock; 1127 + return ; 1130 1128 1129 + mutex_lock(&ar->mutex); 1131 1130 if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) { 1132 1131 err = ar9170_set_operating_mode(ar); 1133 1132 if (err)