diff options
author | Dedy Lansky <qca_dlansky@qca.qualcomm.com> | 2014-09-10 15:34:42 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-11 21:27:38 +0200 |
commit | ec81b5adf42e02560b3b05a0c8897451cd3d8b29 (patch) | |
tree | 20ff75621999758287dcbe03a58d001027b50b82 /drivers/net/wireless/ath/wil6210/debugfs.c | |
parent | wil6210: modify confusing printout (diff) | |
download | linux-ec81b5adf42e02560b3b05a0c8897451cd3d8b29.tar.xz linux-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/debugfs.c')
-rw-r--r-- | drivers/net/wireless/ath/wil6210/debugfs.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index e1f92763c209..21dc437b66a0 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1059,6 +1059,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) { struct wil6210_priv *wil = s->private; int i, tid; + unsigned long flags; for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { struct wil_sta_info *p = &wil->sta[i]; @@ -1079,6 +1080,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) (p->data_port_open ? " data_port_open" : "")); if (p->status == wil_sta_connected) { + spin_lock_irqsave(&p->tid_rx_lock, flags); for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; @@ -1087,6 +1089,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) wil_print_rxtid(s, r); } } + spin_unlock_irqrestore(&p->tid_rx_lock, flags); } } |