From owner-svn-src-user@FreeBSD.ORG Wed Oct 26 15:20:21 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 C9EEB106564A; Wed, 26 Oct 2011 15:20:21 +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 AFDD98FC15; Wed, 26 Oct 2011 15:20:21 +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 p9QFKL61055873; Wed, 26 Oct 2011 15:20:21 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9QFKLxF055870; Wed, 26 Oct 2011 15:20:21 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201110261520.p9QFKLxF055870@svn.freebsd.org> From: Adrian Chadd Date: Wed, 26 Oct 2011 15:20:21 +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: r226794 - 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, 26 Oct 2011 15:20:22 -0000 Author: adrian Date: Wed Oct 26 15:20:21 2011 New Revision: 226794 URL: http://svn.freebsd.org/changeset/base/226794 Log: Now that I've done a quick audit and made sure that the calls to ath_freebuf() occur during active TX completion, migrate the busy flag clear logic to inside ath_freebuf(). ath_freebuf() is now only called for frames which have completed TX somehow (success or failure), or during TX queue flush (where we don't care about the busy flag any longer.) It must not be called for frames that haven't come from the TX completion or node flush logic. This fixes the code to compile/run/not hang w/ the TDMA option in the kernel (but I haven't tested TDMA yet, unfortunately) as now the tail buffer on the free list has the ATH_BUF_BUSY flag cleared on -each- completed subframe. (Again, this isn't the correct/full fix for using multiple TX DMA queues, but that's a later problem to fix. It's just as broken in -HEAD.) Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c user/adrian/if_ath_tx/sys/dev/ath/if_ath_misc.h Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Wed Oct 26 15:17:42 2011 (r226793) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Wed Oct 26 15:20:21 2011 (r226794) @@ -4487,7 +4487,7 @@ ath_tx_update_ratectrl(struct ath_softc * This should be called in the completion function once one * of the buffers has been used. */ -void +static void ath_tx_update_busy(struct ath_softc *sc) { struct ath_buf *last; @@ -4501,11 +4501,10 @@ ath_tx_update_busy(struct ath_softc *sc) * and is no longer referencing the previous * descriptor. */ - ATH_TXBUF_LOCK(sc); + ATH_TXBUF_LOCK_ASSERT(sc); last = TAILQ_LAST(&sc->sc_txbuf, ath_bufhead_s); if (last != NULL) last->bf_flags &= ~ATH_BUF_BUSY; - ATH_TXBUF_UNLOCK(sc); } /* @@ -4594,13 +4593,6 @@ ath_tx_processq(struct ath_softc *sc, st } /* - * Mark the last frame on the buffer list as - * not busy, as the hardware has now moved past - * that "free" entry and onto the next one. - */ - ath_tx_update_busy(sc); - - /* * Call the completion handler. * The completion handler is responsible for * calling the rate control code. @@ -4754,7 +4746,14 @@ ath_tx_proc(void *arg, int npending) #undef TXQACTIVE /* - * Return a buffer to the pool. + * Return a buffer to the pool and update the 'busy' flag on the + * previous 'tail' entry. + * + * This _must_ only be called when the buffer is involved in a completed + * TX. The logic is that if it was part of an active TX, the previous + * buffer on the list is now not involved in a halted TX DMA queue, waiting + * for restart (eg for TDMA.) + * * The caller must free the mbuf and recycle the node reference. */ void @@ -4765,7 +4764,9 @@ ath_freebuf(struct ath_softc *sc, struct KASSERT((bf->bf_node == NULL), ("%s: bf->bf_node != NULL\n", __func__)); KASSERT((bf->bf_m == NULL), ("%s: bf->bf_m != NULL\n", __func__)); + ATH_TXBUF_LOCK(sc); + ath_tx_update_busy(sc); TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); ATH_TXBUF_UNLOCK(sc); } Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_misc.h ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath_misc.h Wed Oct 26 15:17:42 2011 (r226793) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_misc.h Wed Oct 26 15:20:21 2011 (r226794) @@ -63,7 +63,6 @@ extern void ath_tx_default_comp(struct a extern void ath_tx_update_ratectrl(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_rc_series *rc, struct ath_tx_status *ts, int frmlen, int nframes, int nbad); -extern void ath_tx_update_busy(struct ath_softc *sc); extern void ath_tx_freebuf(struct ath_softc *sc, struct ath_buf *bf, int status);