diff options
author | Dedy Lansky <qca_dlansky@qca.qualcomm.com> | 2014-09-10 16:34:42 +0300 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-11 15:27:38 -0400 |
commit | ec81b5adf42e02560b3b05a0c8897451cd3d8b29 (patch) | |
tree | 20ff75621999758287dcbe03a58d001027b50b82 /drivers/net/wireless/ath/wil6210/wmi.c | |
parent | 4cf99c93d24f9cdd338ab23cd671e949ee6ca1bd (diff) | |
download | lwn-ec81b5adf42e02560b3b05a0c8897451cd3d8b29.tar.gz lwn-ec81b5adf42e02560b3b05a0c8897451cd3d8b29.zip |
wil6210: fix race condition between BACK event and Rx data
While handling Rx packet, BACK event arrives and frees tid_ampdu_rx array.
This causes kernel panic while accessing already freed spinlock
The fix is to remove tid_ampdu_rx[]'s spinlock and instead use single
sta's spinlock to guard the whole tid_ampdu_rx array.
Signed-off-by: Dedy Lansky <qca_dlansky@qca.qualcomm.com>
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index ad48f14c305c..c3682c3ae896 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -613,9 +613,17 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr); for (i = 0; i < WIL_STA_TID_NUM; i++) { - struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; + struct wil_tid_ampdu_rx *r; + unsigned long flags; + + spin_lock_irqsave(&sta->tid_rx_lock, flags); + + r = sta->tid_rx[i]; sta->tid_rx[i] = NULL; wil_tid_ampdu_rx_free(wil, r); + + spin_unlock_irqrestore(&sta->tid_rx_lock, flags); + if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize) sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil, evt->agg_wsize, 0); |