From owner-svn-src-user@FreeBSD.ORG Wed Aug 24 08:32:52 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 65FB9106566B; Wed, 24 Aug 2011 08:32:52 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3D0068FC23; Wed, 24 Aug 2011 08:32:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p7O8Wqlh040769; Wed, 24 Aug 2011 08:32:52 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p7O8WqUo040767; Wed, 24 Aug 2011 08:32:52 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201108240832.p7O8WqUo040767@svn.freebsd.org> From: Adrian Chadd Date: Wed, 24 Aug 2011 08:32:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225137 - user/adrian/if_ath_tx/sys/dev/ath X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Aug 2011 08:32:52 -0000 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)