aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-01-14 04:50:15 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-01-14 15:02:21 -0500
commit463e3ed3eacc8f47866e5d612bd8ee0bcee5e2f0 (patch)
tree1de19d4abf710b72044d7ec2854d92f5066d5941 /drivers/net
parenta1fe52801a992e590cdaee2fb47a94bac9b5da90 (diff)
ath9k: remove sc->rx.rxbuflock to fix a deadlock
The commit "ath9k: fix rx flush handling" added a deadlock that happens because ath_rx_tasklet is called in a section that has already taken the rx buffer lock. It seems that the only purpose of the rxbuflock was a band-aid fix to the reset vs rx tasklet race, which has been properly fixed in the commit "ath9k: add a better fix for the rx tasklet vs rx flush race". Now that the fix is in, we can safely remove the lock to avoid such issues. Cc: stable@vger.kernel.org Reported-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c13
2 files changed, 0 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 32b2d5cd9a5a..42794c546a40 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -317,7 +317,6 @@ struct ath_rx {
317 u32 *rxlink; 317 u32 *rxlink;
318 u32 num_pkts; 318 u32 num_pkts;
319 unsigned int rxfilter; 319 unsigned int rxfilter;
320 spinlock_t rxbuflock;
321 struct list_head rxbuf; 320 struct list_head rxbuf;
322 struct ath_descdma rxdma; 321 struct ath_descdma rxdma;
323 struct ath_buf *rx_bufptr; 322 struct ath_buf *rx_bufptr;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 67f58d4bb10e..90752f246970 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -254,8 +254,6 @@ rx_init_fail:
254 254
255static void ath_edma_start_recv(struct ath_softc *sc) 255static void ath_edma_start_recv(struct ath_softc *sc)
256{ 256{
257 spin_lock_bh(&sc->rx.rxbuflock);
258
259 ath9k_hw_rxena(sc->sc_ah); 257 ath9k_hw_rxena(sc->sc_ah);
260 258
261 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, 259 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
267 ath_opmode_init(sc); 265 ath_opmode_init(sc);
268 266
269 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 267 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
270
271 spin_unlock_bh(&sc->rx.rxbuflock);
272} 268}
273 269
274static void ath_edma_stop_recv(struct ath_softc *sc) 270static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -285,7 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
285 int error = 0; 281 int error = 0;
286 282
287 spin_lock_init(&sc->sc_pcu_lock); 283 spin_lock_init(&sc->sc_pcu_lock);
288 spin_lock_init(&sc->rx.rxbuflock);
289 284
290 common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + 285 common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
291 sc->sc_ah->caps.rx_status_len; 286 sc->sc_ah->caps.rx_status_len;
@@ -446,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
446 return 0; 441 return 0;
447 } 442 }
448 443
449 spin_lock_bh(&sc->rx.rxbuflock);
450 if (list_empty(&sc->rx.rxbuf)) 444 if (list_empty(&sc->rx.rxbuf))
451 goto start_recv; 445 goto start_recv;
452 446
@@ -467,8 +461,6 @@ start_recv:
467 ath_opmode_init(sc); 461 ath_opmode_init(sc);
468 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 462 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
469 463
470 spin_unlock_bh(&sc->rx.rxbuflock);
471
472 return 0; 464 return 0;
473} 465}
474 466
@@ -484,7 +476,6 @@ bool ath_stoprecv(struct ath_softc *sc)
484 struct ath_hw *ah = sc->sc_ah; 476 struct ath_hw *ah = sc->sc_ah;
485 bool stopped, reset = false; 477 bool stopped, reset = false;
486 478
487 spin_lock_bh(&sc->rx.rxbuflock);
488 ath9k_hw_abortpcurecv(ah); 479 ath9k_hw_abortpcurecv(ah);
489 ath9k_hw_setrxfilter(ah, 0); 480 ath9k_hw_setrxfilter(ah, 0);
490 stopped = ath9k_hw_stopdmarecv(ah, &reset); 481 stopped = ath9k_hw_stopdmarecv(ah, &reset);
@@ -495,7 +486,6 @@ bool ath_stoprecv(struct ath_softc *sc)
495 ath_edma_stop_recv(sc); 486 ath_edma_stop_recv(sc);
496 else 487 else
497 sc->rx.rxlink = NULL; 488 sc->rx.rxlink = NULL;
498 spin_unlock_bh(&sc->rx.rxbuflock);
499 489
500 if (!(ah->ah_flags & AH_UNPLUGGED) && 490 if (!(ah->ah_flags & AH_UNPLUGGED) &&
501 unlikely(!stopped)) { 491 unlikely(!stopped)) {
@@ -1059,7 +1049,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1059 dma_type = DMA_FROM_DEVICE; 1049 dma_type = DMA_FROM_DEVICE;
1060 1050
1061 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; 1051 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
1062 spin_lock_bh(&sc->rx.rxbuflock);
1063 1052
1064 tsf = ath9k_hw_gettsf64(ah); 1053 tsf = ath9k_hw_gettsf64(ah);
1065 tsf_lower = tsf & 0xffffffff; 1054 tsf_lower = tsf & 0xffffffff;
@@ -1254,8 +1243,6 @@ requeue:
1254 } 1243 }
1255 } while (1); 1244 } while (1);
1256 1245
1257 spin_unlock_bh(&sc->rx.rxbuflock);
1258
1259 if (!(ah->imask & ATH9K_INT_RXEOL)) { 1246 if (!(ah->imask & ATH9K_INT_RXEOL)) {
1260 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); 1247 ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
1261 ath9k_hw_set_interrupts(ah); 1248 ath9k_hw_set_interrupts(ah);