svn commit: r225137 - user/adrian/if_ath_tx/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Wed Aug 24 08:32:52 UTC 2011
Author: adrian
Date: Wed Aug 24 08:32:51 2011
New Revision: 225137
URL: http://svn.freebsd.org/changeset/base/225137
Log:
Fix a TX hang that crept in when I flipped in ATH_BUF_BUSY / TX buf cloning.
This was due to an ATH_BUF_BUSY buffer ending up at the head of the txbuf list,
causing ath_getbuf() to halt TX until the TX queue had caught up. Since the
TX queue wasn't -really- full, TX would stay paused.
The basic problem: because I just checked the busy flag, the:
* buffer would be cloned; the ATH_BUF_BUSY tagged buffer would be freed
and tossed onto the end of the list;
* if the new cloned buffer (not busy) was already at max retries, the
new non-busy buffer would be freed, and added to the end of the list;
and thus the busy buffer isn't at the end of the list;
* .. and bewm. The flag would never be cleared.
Also, whilst I'm at it, add a comment about an error condition if the buffer
can't be cloned - i may end up confusing the DMA code a bit. I'll sort that
out later.
Modified:
user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Wed Aug 24 08:27:00 2011 (r225136)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Wed Aug 24 08:32:51 2011 (r225137)
@@ -2372,6 +2372,7 @@ ath_tx_retry_clone(struct ath_softc *sc,
device_printf(sc->sc_dev,
"%s: failed to setup dma for clone\n",
__func__);
+ /* XXX this frees the dmasetup that failed above? */
ath_freebuf(sc, nbf);
return NULL;
}
@@ -2412,7 +2413,8 @@ ath_tx_aggr_retry_unaggr(struct ath_soft
* to force the next bit of code to free the buffer
* for us.
*/
- if (bf->bf_flags & ATH_BUF_BUSY) {
+ if ((bf->bf_state.bfs_retries < SWMAX_RETRIES) &&
+ (bf->bf_flags & ATH_BUF_BUSY)) {
struct ath_buf *nbf;
nbf = ath_tx_retry_clone(sc, bf);
if (nbf)
@@ -2517,7 +2519,8 @@ ath_tx_retry_subframe(struct ath_softc *
* to force the next bit of code to free the buffer
* for us.
*/
- if (bf->bf_flags & ATH_BUF_BUSY) {
+ if ((bf->bf_state.bfs_retries < SWMAX_RETRIES) &&
+ (bf->bf_flags & ATH_BUF_BUSY)) {
struct ath_buf *nbf;
nbf = ath_tx_retry_clone(sc, bf);
if (nbf)
More information about the svn-src-user
mailing list