Date: Sun, 2 Dec 2012 06:24:08 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243786 - head/sys/dev/ath Message-ID: <201212020624.qB26O81n097804@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Sun Dec 2 06:24:08 2012 New Revision: 243786 URL: http://svnweb.freebsd.org/changeset/base/243786 Log: Delete the per-TXQ locks and replace them with a single TX lock. I couldn't think of a way to maintain the hardware TXQ locks _and_ layer on top of that per-TXQ software queuing and any other kind of fine-grained locks (eg per-TID, or per-node locks.) So for now, to facilitate some further code refactoring and development as part of the final push to get software queue ps-poll and u-apsd handling into this driver, just do away with them entirely. I may eventually bring them back at some point, when it looks slightly more architectually cleaner to do so. But as it stands at the present, it's not really buying us much: * in order to properly serialise things and not get bitten by scheduling and locking interactions with things higher up in the stack, we need to wrap the whole TX path in a long held lock. Otherwise we can end up being pre-empted during frame handling, resulting in some out of order frame handling between sequence number allocation and encryption handling (ie, the seqno and the CCMP IV get out of sequence); * .. so whilst that's the case, holding the lock for that long means that we're acquiring and releasing the TXQ lock _inside_ that context; * And we also acquire it per-frame during frame completion, but we currently can't hold the lock for the duration of the TX completion as we need to call net80211 layer things with the locks _unheld_ to avoid LOR. * .. the other places were grab that lock are reset/flush, which don't happen often. My eventual aim is to change the TX path so all rejected frame transmissions and all frame completions result in any ieee80211_free_node() calls to occur outside of the TX lock; then I can cut back on the amount of locking that goes on here. There may be some LORs that occur when ieee80211_free_node() is called when the TX queue path fails; I'll begin to address these in follow-up commits. Modified: head/sys/dev/ath/if_ath.c head/sys/dev/ath/if_ath_beacon.c head/sys/dev/ath/if_ath_tx.c head/sys/dev/ath/if_ath_tx_edma.c head/sys/dev/ath/if_ath_tx_ht.c head/sys/dev/ath/if_athvar.h Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Sun Dec 2 05:57:53 2012 (r243785) +++ head/sys/dev/ath/if_ath.c Sun Dec 2 06:24:08 2012 (r243786) @@ -1369,7 +1369,6 @@ ath_vap_delete(struct ieee80211vap *vap) * Reclaim any pending mcast frames for the vap. */ ath_tx_draintxq(sc, &avp->av_mcastq); - ATH_TXQ_LOCK_DESTROY(&avp->av_mcastq); } /* * Update bookkeeping. @@ -2271,16 +2270,16 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T /* Restart TX/RX as needed */ ath_txrx_start(sc); - /* XXX Restart TX completion and pending TX */ + /* Restart TX completion and pending TX */ if (reset_type == ATH_RESET_NOLOSS) { + ATH_TX_LOCK(sc); for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - ATH_TXQ_LOCK(&sc->sc_txq[i]); ath_txq_restart_dma(sc, &sc->sc_txq[i]); ath_txq_sched(sc, &sc->sc_txq[i]); - ATH_TXQ_UNLOCK(&sc->sc_txq[i]); } } + ATH_TX_UNLOCK(sc); } /* @@ -2513,7 +2512,9 @@ ath_start_task(void *arg, int npending) sc->sc_txstart_cnt++; ATH_PCU_UNLOCK(sc); + ATH_TX_LOCK(sc); ath_start(sc->sc_ifp); + ATH_TX_UNLOCK(sc); ATH_PCU_LOCK(sc); sc->sc_txstart_cnt--; @@ -2534,6 +2535,8 @@ ath_start(struct ifnet *ifp) if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) return; + ATH_TX_LOCK_ASSERT(sc); + ATH_KTR(sc, ATH_KTR_TX, 0, "ath_start: called"); for (;;) { @@ -2605,6 +2608,10 @@ ath_start(struct ifnet *ifp) ath_returnbuf_head(sc, bf); ath_txfrag_cleanup(sc, &frags, ni); ATH_TXBUF_UNLOCK(sc); + /* + * XXX todo, free the node outside of + * the TX lock context! + */ if (ni != NULL) ieee80211_free_node(ni); continue; @@ -2816,9 +2823,6 @@ void ath_txqmove(struct ath_txq *dst, struct ath_txq *src) { - ATH_TXQ_LOCK_ASSERT(dst); - ATH_TXQ_LOCK_ASSERT(src); - TAILQ_CONCAT(&dst->axq_q, &src->axq_q, bf_list); dst->axq_link = src->axq_link; src->axq_link = NULL; @@ -3298,7 +3302,6 @@ ath_txq_init(struct ath_softc *sc, struc txq->axq_softc = sc; TAILQ_INIT(&txq->axq_q); TAILQ_INIT(&txq->axq_tidq); - ATH_TXQ_LOCK_INIT(sc, txq); } /* @@ -3482,7 +3485,6 @@ ath_tx_cleanupq(struct ath_softc *sc, st { ath_hal_releasetxqueue(sc->sc_ah, txq->axq_qnum); - ATH_TXQ_LOCK_DESTROY(txq); sc->sc_txqsetup &= ~(1<<txq->axq_qnum); } @@ -3691,7 +3693,7 @@ ath_tx_process_buf_completion(struct ath struct ieee80211_node *ni = bf->bf_node; struct ath_node *an = NULL; - ATH_TXQ_UNLOCK_ASSERT(txq); + ATH_TX_UNLOCK_ASSERT(sc); /* If unicast frame, update general statistics */ if (ni != NULL) { @@ -3760,11 +3762,11 @@ ath_tx_processq(struct ath_softc *sc, st nacked = 0; for (;;) { - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); txq->axq_intrcnt = 0; /* reset periodic desc intr count */ bf = TAILQ_FIRST(&txq->axq_q); if (bf == NULL) { - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); break; } ds = bf->bf_lastds; /* XXX must be setup correctly! */ @@ -3792,7 +3794,7 @@ ath_tx_processq(struct ath_softc *sc, st ATH_KTR(sc, ATH_KTR_TXCOMP, 3, "ath_tx_processq: txq=%u, bf=%p ds=%p, HAL_EINPROGRESS", txq->axq_qnum, bf, ds); - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); break; } ATH_TXQ_REMOVE(txq, bf, bf_list); @@ -3833,7 +3835,7 @@ ath_tx_processq(struct ath_softc *sc, st ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, ts->ts_rssi); } - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); /* * Update statistics and call completion @@ -3852,9 +3854,9 @@ ath_tx_processq(struct ath_softc *sc, st /* Kick the TXQ scheduler */ if (dosched) { - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); ath_txq_sched(sc, txq); - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); } ATH_KTR(sc, ATH_KTR_TXCOMP, 1, @@ -4027,13 +4029,13 @@ ath_txq_sched_tasklet(void *arg, int npe sc->sc_txproc_cnt++; ATH_PCU_UNLOCK(sc); + ATH_TX_LOCK(sc); for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - ATH_TXQ_LOCK(&sc->sc_txq[i]); ath_txq_sched(sc, &sc->sc_txq[i]); - ATH_TXQ_UNLOCK(&sc->sc_txq[i]); } } + ATH_TX_UNLOCK(sc); ATH_PCU_LOCK(sc); sc->sc_txproc_cnt--; @@ -4166,7 +4168,7 @@ ath_tx_draintxq(struct ath_softc *sc, st ATH_TXBUF_UNLOCK(sc); for (ix = 0;; ix++) { - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); bf = TAILQ_FIRST(&txq->axq_q); if (bf == NULL) { txq->axq_link = NULL; @@ -4181,7 +4183,7 @@ ath_tx_draintxq(struct ath_softc *sc, st * very fruity very quickly. */ txq->axq_fifo_depth = 0; - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); break; } ATH_TXQ_REMOVE(txq, bf, bf_list); @@ -4217,7 +4219,7 @@ ath_tx_draintxq(struct ath_softc *sc, st * Clear ATH_BUF_BUSY; the completion handler * will free the buffer. */ - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); bf->bf_flags &= ~ATH_BUF_BUSY; if (bf->bf_comp) bf->bf_comp(sc, bf, 1); Modified: head/sys/dev/ath/if_ath_beacon.c ============================================================================== --- head/sys/dev/ath/if_ath_beacon.c Sun Dec 2 05:57:53 2012 (r243785) +++ head/sys/dev/ath/if_ath_beacon.c Sun Dec 2 06:24:08 2012 (r243786) @@ -564,8 +564,7 @@ ath_beacon_generate(struct ath_softc *sc struct ath_hal *ah = sc->sc_ah; /* NB: only at DTIM */ - ATH_TXQ_LOCK(cabq); - ATH_TXQ_LOCK(&avp->av_mcastq); + ATH_TX_LOCK(sc); if (nmcastq) { struct ath_buf *bfm; @@ -586,8 +585,7 @@ ath_beacon_generate(struct ath_softc *sc /* NB: gated by beacon so safe to start here */ if (! TAILQ_EMPTY(&(cabq->axq_q))) ath_hal_txstart(ah, cabq->axq_qnum); - ATH_TXQ_UNLOCK(&avp->av_mcastq); - ATH_TXQ_UNLOCK(cabq); + ATH_TX_UNLOCK(sc); } return bf; } Modified: head/sys/dev/ath/if_ath_tx.c ============================================================================== --- head/sys/dev/ath/if_ath_tx.c Sun Dec 2 05:57:53 2012 (r243785) +++ head/sys/dev/ath/if_ath_tx.c Sun Dec 2 06:24:08 2012 (r243786) @@ -708,7 +708,8 @@ static void ath_tx_handoff_mcast(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf) { - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); + KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0, ("%s: busy status 0x%x", __func__, bf->bf_flags)); if (txq->axq_link != NULL) { @@ -745,7 +746,7 @@ ath_tx_handoff_hw(struct ath_softc *sc, * the SWBA handler since frames only go out on DTIM and * to avoid possible races. */ - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0, ("%s: busy status 0x%x", __func__, bf->bf_flags)); KASSERT(txq->axq_qnum != ATH_TXQ_SWQ, @@ -924,7 +925,7 @@ ath_legacy_tx_dma_restart(struct ath_sof struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf, *bf_last; - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); /* This is always going to be cleared, empty or not */ txq->axq_flags &= ~ATH_TXQ_PUTPENDING; @@ -950,7 +951,7 @@ static void ath_legacy_xmit_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf) { - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); #ifdef ATH_DEBUG_ALQ if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) @@ -1395,7 +1396,7 @@ ath_tx_update_clrdmask(struct ath_softc struct ath_buf *bf) { - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); if (tid->clrdmask == 1) { bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; @@ -1421,7 +1422,7 @@ ath_tx_xmit_normal(struct ath_softc *sc, struct ath_node *an = ATH_NODE(bf->bf_node); struct ath_tid *tid = &an->an_tid[bf->bf_state.bfs_tid]; - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); /* * For now, just enable CLRDMASK. ath_tx_xmit_normal() does @@ -1492,7 +1493,7 @@ ath_tx_normal_setup(struct ath_softc *sc * re-ordered frames to have out of order CCMP PN's, resulting * in many, many frame drops. */ - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); wh = mtod(m0, struct ieee80211_frame *); iswep = wh->i_fc[1] & IEEE80211_FC1_WEP; @@ -1788,6 +1789,8 @@ ath_tx_start(struct ath_softc *sc, struc ieee80211_seq seqno; uint8_t type, subtype; + ATH_TX_LOCK_ASSERT(sc); + /* * Determine the target hardware queue. * @@ -1817,15 +1820,10 @@ ath_tx_start(struct ath_softc *sc, struc * XXX duplicated in ath_raw_xmit(). */ if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - ATH_TXQ_LOCK(sc->sc_cabq); - if (sc->sc_cabq->axq_depth > sc->sc_txq_mcastq_maxdepth) { sc->sc_stats.ast_tx_mcastq_overflow++; r = ENOBUFS; } - - ATH_TXQ_UNLOCK(sc->sc_cabq); - if (r != 0) { m_freem(m0); return r; @@ -1867,16 +1865,6 @@ ath_tx_start(struct ath_softc *sc, struc /* XXX should just bzero the bf_state? */ bf->bf_state.bfs_dobaw = 0; - /* - * Acquire the TXQ lock early, so both the encap and seqno - * are allocated together. - * - * XXX should TXQ for CABQ traffic be the multicast queue, - * or the TXQ the given PRI would allocate from? (eg for - * sequence number allocation locking.) - */ - ATH_TXQ_LOCK(txq); - /* A-MPDU TX? Manually set sequence number */ /* * Don't do it whilst pending; the net80211 layer still @@ -1964,8 +1952,6 @@ ath_tx_start(struct ath_softc *sc, struc ath_tx_xmit_normal(sc, txq, bf); #endif done: - ATH_TXQ_UNLOCK(txq); - return 0; } @@ -1990,6 +1976,8 @@ ath_tx_raw_start(struct ath_softc *sc, s int o_tid = -1; int do_override; + ATH_TX_LOCK_ASSERT(sc); + wh = mtod(m0, struct ieee80211_frame *); ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); hdrlen = ieee80211_anyhdrsize(wh); @@ -2024,8 +2012,6 @@ ath_tx_raw_start(struct ath_softc *sc, s pri = TID_TO_WME_AC(o_tid); } - ATH_TXQ_LOCK(sc->sc_ac2q[pri]); - /* Handle encryption twiddling if needed */ if (! ath_tx_tag_crypto(sc, ni, m0, params->ibp_flags & IEEE80211_BPF_CRYPTO, 0, @@ -2188,8 +2174,6 @@ ath_tx_raw_start(struct ath_softc *sc, s bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; ath_tx_xmit_normal(sc, sc->sc_ac2q[pri], bf); #endif - ATH_TXQ_UNLOCK(sc->sc_ac2q[pri]); - return 0; } @@ -2237,15 +2221,11 @@ ath_raw_xmit(struct ieee80211_node *ni, * XXX duplicated in ath_tx_start(). */ if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - ATH_TXQ_LOCK(sc->sc_cabq); - if (sc->sc_cabq->axq_depth > sc->sc_txq_mcastq_maxdepth) { sc->sc_stats.ast_tx_mcastq_overflow++; error = ENOBUFS; } - ATH_TXQ_UNLOCK(sc->sc_cabq); - if (error != 0) { m_freem(m); goto bad; @@ -2435,8 +2415,7 @@ ath_tx_addto_baw(struct ath_softc *sc, s int index, cindex; struct ieee80211_tx_ampdu *tap; - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); if (bf->bf_state.bfs_isretried) return; @@ -2531,8 +2510,7 @@ ath_tx_switch_baw_buf(struct ath_softc * struct ieee80211_tx_ampdu *tap; int seqno = SEQNO(old_bf->bf_state.bfs_seqno); - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); tap = ath_tx_get_tx_tid(an, tid->tid); index = ATH_BA_INDEX(tap->txa_start, seqno); @@ -2580,8 +2558,7 @@ ath_tx_update_baw(struct ath_softc *sc, struct ieee80211_tx_ampdu *tap; int seqno = SEQNO(bf->bf_state.bfs_seqno); - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); tap = ath_tx_get_tx_tid(an, tid->tid); index = ATH_BA_INDEX(tap->txa_start, seqno); @@ -2637,7 +2614,7 @@ ath_tx_tid_sched(struct ath_softc *sc, s { struct ath_txq *txq = sc->sc_ac2q[tid->ac]; - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); if (tid->paused) return; /* paused, can't schedule yet */ @@ -2661,7 +2638,7 @@ ath_tx_tid_unsched(struct ath_softc *sc, { struct ath_txq *txq = sc->sc_ac2q[tid->ac]; - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); if (tid->sched == 0) return; @@ -2697,7 +2674,7 @@ ath_tx_tid_seqno_assign(struct ath_softc if (! IEEE80211_QOS_HAS_SEQ(wh)) return -1; - ATH_TID_LOCK_ASSERT(sc, &(ATH_NODE(ni)->an_tid[tid])); + ATH_TX_LOCK_ASSERT(sc); /* * Is it a QOS NULL Data frame? Give it a sequence number from @@ -2746,8 +2723,7 @@ ath_tx_xmit_aggr(struct ath_softc *sc, s bf->bf_state.bfs_txq->axq_qnum); } - ATH_TXQ_LOCK_ASSERT(txq); - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); tap = ath_tx_get_tx_tid(an, tid->tid); @@ -2832,7 +2808,7 @@ ath_tx_swq(struct ath_softc *sc, struct int pri, tid; struct mbuf *m0 = bf->bf_m; - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); /* Fetch the TID - non-QoS frames get assigned to TID 16 */ wh = mtod(m0, struct ieee80211_frame *); @@ -2840,8 +2816,6 @@ ath_tx_swq(struct ath_softc *sc, struct tid = ath_tx_gettid(sc, m0); atid = &an->an_tid[tid]; - ATH_TID_LOCK_ASSERT(sc, atid); - DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p, pri=%d, tid=%d, qos=%d\n", __func__, bf, pri, tid, IEEE80211_QOS_HAS_SEQ(wh)); @@ -2970,7 +2944,7 @@ static void ath_tx_tid_pause(struct ath_softc *sc, struct ath_tid *tid) { - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); + ATH_TX_LOCK_ASSERT(sc); tid->paused++; DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: paused = %d\n", __func__, tid->paused); @@ -2982,7 +2956,8 @@ ath_tx_tid_pause(struct ath_softc *sc, s static void ath_tx_tid_resume(struct ath_softc *sc, struct ath_tid *tid) { - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); + + ATH_TX_LOCK_ASSERT(sc); tid->paused--; @@ -3022,7 +2997,8 @@ ath_tx_tid_filt_addbuf(struct ath_softc struct ath_buf *bf) { - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); + if (! tid->isfiltered) device_printf(sc->sc_dev, "%s: not filtered?!\n", __func__); @@ -3045,7 +3021,7 @@ ath_tx_tid_filt_comp_buf(struct ath_soft struct ath_buf *bf) { - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); if (! tid->isfiltered) { DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: filter transition\n", @@ -3070,7 +3046,7 @@ ath_tx_tid_filt_comp_complete(struct ath { struct ath_buf *bf; - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); if (tid->hwq_depth != 0) return; @@ -3104,7 +3080,7 @@ ath_tx_tid_filt_comp_single(struct ath_s struct ath_buf *nbf; int retval; - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); /* * Don't allow a filtered frame to live forever. @@ -3152,7 +3128,7 @@ ath_tx_tid_filt_comp_aggr(struct ath_sof { struct ath_buf *bf, *bf_next, *nbf; - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); bf = bf_first; while (bf) { @@ -3207,7 +3183,8 @@ next: static void ath_tx_tid_bar_suspend(struct ath_softc *sc, struct ath_tid *tid) { - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); + + ATH_TX_LOCK_ASSERT(sc); DPRINTF(sc, ATH_DEBUG_SW_TX_BAR, "%s: tid=%p, bar_wait=%d, bar_tx=%d, called\n", @@ -3240,7 +3217,8 @@ ath_tx_tid_bar_suspend(struct ath_softc static void ath_tx_tid_bar_unsuspend(struct ath_softc *sc, struct ath_tid *tid) { - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); + + ATH_TX_LOCK_ASSERT(sc); DPRINTF(sc, ATH_DEBUG_SW_TX_BAR, "%s: tid=%p, called\n", @@ -3265,7 +3243,7 @@ static int ath_tx_tid_bar_tx_ready(struct ath_softc *sc, struct ath_tid *tid) { - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); + ATH_TX_LOCK_ASSERT(sc); if (tid->bar_wait == 0 || tid->hwq_depth > 0) return (0); @@ -3293,7 +3271,7 @@ ath_tx_tid_bar_tx(struct ath_softc *sc, { struct ieee80211_tx_ampdu *tap; - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); + ATH_TX_LOCK_ASSERT(sc); DPRINTF(sc, ATH_DEBUG_SW_TX_BAR, "%s: tid=%p, called\n", @@ -3349,15 +3327,15 @@ ath_tx_tid_bar_tx(struct ath_softc *sc, /* Try sending the BAR frame */ /* We can't hold the lock here! */ - ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]); + ATH_TX_UNLOCK(sc); if (ieee80211_send_bar(&tid->an->an_node, tap, tap->txa_start) == 0) { /* Success? Now we wait for notification that it's done */ - ATH_TXQ_LOCK(sc->sc_ac2q[tid->ac]); + ATH_TX_LOCK(sc); return; } /* Failure? For now, warn loudly and continue */ - ATH_TXQ_LOCK(sc->sc_ac2q[tid->ac]); + ATH_TX_LOCK(sc); device_printf(sc->sc_dev, "%s: tid=%p, failed to TX BAR, continue!\n", __func__, tid); ath_tx_tid_bar_unsuspend(sc, tid); @@ -3368,7 +3346,7 @@ ath_tx_tid_drain_pkt(struct ath_softc *s struct ath_tid *tid, ath_bufhead *bf_cq, struct ath_buf *bf) { - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); /* * If the current TID is running AMPDU, update @@ -3471,7 +3449,7 @@ ath_tx_tid_drain(struct ath_softc *sc, s tap = ath_tx_get_tx_tid(an, tid->tid); - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); /* Walk the queue, free frames */ t = 0; @@ -3559,17 +3537,16 @@ ath_tx_node_flush(struct ath_softc *sc, ATH_KTR(sc, ATH_KTR_NODE, 1, "ath_tx_node_flush: flush node; ni=%p", &an->an_node); + ATH_TX_LOCK(sc); for (tid = 0; tid < IEEE80211_TID_SIZE; tid++) { struct ath_tid *atid = &an->an_tid[tid]; - struct ath_txq *txq = sc->sc_ac2q[atid->ac]; - ATH_TXQ_LOCK(txq); /* Free packets */ ath_tx_tid_drain(sc, an, atid, &bf_cq); /* Remove this tid from the list of active tids */ ath_tx_tid_unsched(sc, atid); - ATH_TXQ_UNLOCK(txq); } + ATH_TX_UNLOCK(sc); /* Handle completed frames */ while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { @@ -3589,7 +3566,7 @@ ath_tx_txq_drain(struct ath_softc *sc, s struct ath_buf *bf; TAILQ_INIT(&bf_cq); - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); /* * Iterate over all active tids for the given txq, @@ -3601,7 +3578,7 @@ ath_tx_txq_drain(struct ath_softc *sc, s ath_tx_tid_unsched(sc, tid); } - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { TAILQ_REMOVE(&bf_cq, bf, bf_list); @@ -3635,7 +3612,7 @@ ath_tx_normal_comp(struct ath_softc *sc, struct ath_tx_status *ts = &bf->bf_status.ds_txstat; /* The TID state is protected behind the TXQ lock */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: fail=%d, hwq_depth now %d\n", __func__, bf, fail, atid->hwq_depth - 1); @@ -3676,7 +3653,7 @@ ath_tx_normal_comp(struct ath_softc *sc, */ if (atid->isfiltered) ath_tx_tid_filt_comp_complete(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* * punt to rate control if we're not being cleaned up @@ -3708,7 +3685,7 @@ ath_tx_comp_cleanup_unaggr(struct ath_so DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: TID %d: incomp=%d\n", __func__, tid, atid->incomp); - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); atid->incomp--; if (atid->incomp == 0) { DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, @@ -3717,7 +3694,7 @@ ath_tx_comp_cleanup_unaggr(struct ath_so atid->cleanup_inprogress = 0; ath_tx_tid_resume(sc, atid); } - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); ath_tx_default_comp(sc, bf, 0); } @@ -3745,7 +3722,7 @@ ath_tx_tid_cleanup(struct ath_softc *sc, "%s: TID %d: called\n", __func__, tid); TAILQ_INIT(&bf_cq); - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); /* * Move the filtered frames to the TX queue, before @@ -3827,7 +3804,7 @@ ath_tx_tid_cleanup(struct ath_softc *sc, DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: TID %d: cleanup needed: %d packets\n", __func__, tid, atid->incomp); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* Handle completing frames and fail them */ while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { @@ -3907,7 +3884,7 @@ ath_tx_aggr_retry_unaggr(struct ath_soft struct ath_tid *atid = &an->an_tid[tid]; struct ieee80211_tx_ampdu *tap; - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); tap = ath_tx_get_tx_tid(an, tid); @@ -3953,7 +3930,7 @@ ath_tx_aggr_retry_unaggr(struct ath_soft if (ath_tx_tid_bar_tx_ready(sc, atid)) ath_tx_tid_bar_tx(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* Free buffer, bf is free after this call */ ath_tx_default_comp(sc, bf, 0); @@ -3978,7 +3955,7 @@ ath_tx_aggr_retry_unaggr(struct ath_soft if (ath_tx_tid_bar_tx_ready(sc, atid)) ath_tx_tid_bar_tx(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); } /* @@ -3997,7 +3974,7 @@ ath_tx_retry_subframe(struct ath_softc * int tid = bf->bf_state.bfs_tid; struct ath_tid *atid = &an->an_tid[tid]; - ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK_ASSERT(sc); /* XXX clr11naggr should be done for all subframes */ ath_hal_clr11n_aggr(sc->sc_ah, bf->bf_desc); @@ -4080,7 +4057,7 @@ ath_tx_comp_aggr_error(struct ath_softc bf_first->bf_state.bfs_pktlen, bf_first->bf_state.bfs_nframes, bf_first->bf_state.bfs_nframes); - ATH_TXQ_LOCK(sc->sc_ac2q[tid->ac]); + ATH_TX_LOCK(sc); tap = ath_tx_get_tx_tid(an, tid->tid); sc->sc_stats.ast_tx_aggr_failall++; @@ -4127,7 +4104,7 @@ ath_tx_comp_aggr_error(struct ath_softc if (ath_tx_tid_bar_tx_ready(sc, tid)) ath_tx_tid_bar_tx(sc, tid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]); + ATH_TX_UNLOCK(sc); /* Complete frames which errored out */ while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { @@ -4153,7 +4130,7 @@ ath_tx_comp_cleanup_aggr(struct ath_soft bf = bf_first; - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); /* update incomp */ while (bf) { @@ -4174,7 +4151,7 @@ ath_tx_comp_cleanup_aggr(struct ath_soft if (ath_tx_tid_bar_tx_ready(sc, atid)) ath_tx_tid_bar_tx(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* Handle frame completion */ while (bf) { @@ -4230,7 +4207,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc * TAILQ_INIT(&bf_cq); /* The TID state is kept behind the TXQ lock */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); atid->hwq_depth--; if (atid->hwq_depth < 0) @@ -4255,7 +4232,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc * device_printf(sc->sc_dev, "%s: isfiltered=1, normal_comp?\n", __func__); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); ath_tx_comp_cleanup_aggr(sc, bf_first); return; } @@ -4319,7 +4296,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc * if (ts.ts_status & HAL_TXERR_XRETRY) { #endif if (ts.ts_status != 0) { - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); ath_tx_comp_aggr_error(sc, bf_first, atid); return; } @@ -4438,7 +4415,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc * * TXed. */ txseq = tap->txa_start; - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); if (nframes != nf) device_printf(sc->sc_dev, @@ -4458,15 +4435,15 @@ ath_tx_aggr_comp_aggr(struct ath_softc * */ if (drops) { /* Suspend the TX queue and get ready to send the BAR */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); ath_tx_tid_bar_suspend(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); } DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: txa_start now %d\n", __func__, tap->txa_start); - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); /* Prepend all frames to the beginning of the queue */ while ((bf = TAILQ_LAST(&bf_q, ath_bufhead_s)) != NULL) { @@ -4500,7 +4477,7 @@ finish_send_bar: if (ath_tx_tid_bar_tx_ready(sc, atid)) ath_tx_tid_bar_tx(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* Do deferred completion */ while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { @@ -4549,7 +4526,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc * This unfortunately means that it's released and regrabbed * during retry and cleanup. That's rather inefficient. */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); if (tid == IEEE80211_NONQOS_TID) device_printf(sc->sc_dev, "%s: TID=16!\n", __func__); @@ -4583,7 +4560,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc device_printf(sc->sc_dev, "%s: isfiltered=1, normal_comp?\n", __func__); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: cleanup_unaggr\n", __func__); ath_tx_comp_cleanup_unaggr(sc, bf); @@ -4639,7 +4616,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc if (ath_tx_tid_bar_tx_ready(sc, atid)) ath_tx_tid_bar_tx(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* * If freeframe is set, then the frame couldn't be * cloned and bf is still valid. Just complete/free it. @@ -4658,7 +4635,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc if (fail == 0 && ts->ts_status & HAL_TXERR_XRETRY) { #endif if (fail == 0 && ts.ts_status != 0) { - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: retry_unaggr\n", __func__); ath_tx_aggr_retry_unaggr(sc, bf); @@ -4696,7 +4673,7 @@ ath_tx_aggr_comp_unaggr(struct ath_softc if (ath_tx_tid_bar_tx_ready(sc, atid)) ath_tx_tid_bar_tx(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); ath_tx_default_comp(sc, bf, fail); /* bf is freed at this point */ @@ -4727,7 +4704,7 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft ath_bufhead bf_q; DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: tid=%d\n", __func__, tid->tid); - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); tap = ath_tx_get_tx_tid(an, tid->tid); @@ -4933,7 +4910,7 @@ ath_tx_tid_hw_queue_norm(struct ath_soft DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: node %p: TID %d: called\n", __func__, an, tid->tid); - ATH_TID_LOCK_ASSERT(sc, tid); + ATH_TX_LOCK_ASSERT(sc); /* Check - is AMPDU pending or running? then print out something */ if (ath_tx_ampdu_pending(sc, an, tid->tid)) @@ -5012,7 +4989,7 @@ ath_txq_sched(struct ath_softc *sc, stru { struct ath_tid *tid, *next, *last; - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TX_LOCK_ASSERT(sc); /* * Don't schedule if the hardware queue is busy. @@ -5162,7 +5139,7 @@ ath_addba_request(struct ieee80211_node * it'll be "after" the left edge of the BAW and thus it'll * fall within it. */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); /* * This is a bit annoying. Until net80211 HT code inherits some * (any) locking, we may have this called in parallel BUT only @@ -5172,7 +5149,7 @@ ath_addba_request(struct ieee80211_node ath_tx_tid_pause(sc, atid); atid->addba_tx_pending = 1; } - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: called; dialogtoken=%d, baparamset=%d, batimeout=%d\n", @@ -5231,7 +5208,7 @@ ath_addba_response(struct ieee80211_node */ r = sc->sc_addba_response(ni, tap, status, code, batimeout); - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); atid->addba_tx_pending = 0; /* * XXX dirty! @@ -5240,7 +5217,7 @@ ath_addba_response(struct ieee80211_node */ tap->txa_start = ni->ni_txseqs[tid]; ath_tx_tid_resume(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); return r; } @@ -5265,7 +5242,7 @@ ath_addba_stop(struct ieee80211_node *ni * Pause TID traffic early, so there aren't any races * Unblock the pending BAR held traffic, if it's currently paused. */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); ath_tx_tid_pause(sc, atid); if (atid->bar_wait) { /* @@ -5276,7 +5253,7 @@ ath_addba_stop(struct ieee80211_node *ni atid->bar_tx = 1; ath_tx_tid_bar_unsuspend(sc, atid); } - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* There's no need to hold the TXQ lock here */ sc->sc_addba_stop(ni, tap); @@ -5332,7 +5309,7 @@ ath_bar_response(struct ieee80211_node * * has beaten us to the punch? (XXX figure out what?) */ if (status == 0 || attempts == 50) { - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); if (atid->bar_tx == 0 || atid->bar_wait == 0) device_printf(sc->sc_dev, "%s: huh? bar_tx=%d, bar_wait=%d\n", @@ -5340,7 +5317,7 @@ ath_bar_response(struct ieee80211_node * atid->bar_tx, atid->bar_wait); else ath_tx_tid_bar_unsuspend(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); } } @@ -5360,17 +5337,17 @@ ath_addba_response_timeout(struct ieee80 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: called; resuming\n", __func__); - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); atid->addba_tx_pending = 0; - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); /* Note: This updates the aggregate state to (again) pending */ sc->sc_addba_response_timeout(ni, tap); /* Unpause the TID; which reschedules it */ - ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_LOCK(sc); ath_tx_tid_resume(sc, atid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + ATH_TX_UNLOCK(sc); } /* @@ -5438,14 +5415,14 @@ ath_tx_node_sleep(struct ath_softc *sc, */ /* Suspend all traffic on the node */ + ATH_TX_LOCK(sc); for (tid = 0; tid < IEEE80211_TID_SIZE; tid++) { atid = &an->an_tid[tid]; txq = sc->sc_ac2q[atid->ac]; - ATH_TXQ_LOCK(txq); ath_tx_tid_pause(sc, atid); - ATH_TXQ_UNLOCK(txq); } + ATH_TX_UNLOCK(sc); ATH_NODE_LOCK(an); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212020624.qB26O81n097804>