diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-01-14 04:50:15 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-01-14 15:02:21 -0500 |
commit | 463e3ed3eacc8f47866e5d612bd8ee0bcee5e2f0 (patch) | |
tree | 1de19d4abf710b72044d7ec2854d92f5066d5941 /drivers/net | |
parent | a1fe52801a992e590cdaee2fb47a94bac9b5da90 (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.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 13 |
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 | ||
255 | static void ath_edma_start_recv(struct ath_softc *sc) | 255 | static 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 | ||
274 | static void ath_edma_stop_recv(struct ath_softc *sc) | 270 | static 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); |