Date: Wed, 24 Aug 2011 08:32:52 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r225137 - user/adrian/if_ath_tx/sys/dev/ath Message-ID: <201108240832.p7O8WqUo040767@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108240832.p7O8WqUo040767>