Date: Thu, 7 Feb 2013 07:50:17 +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: r246453 - head/sys/dev/ath Message-ID: <201302070750.r177oHiC058531@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Thu Feb 7 07:50:16 2013 New Revision: 246453 URL: http://svnweb.freebsd.org/changeset/base/246453 Log: Create a new TX lock specifically for queuing frames. This now separates out the act of queuing frames from the act of running TX and TX completion. Modified: head/sys/dev/ath/if_ath.c head/sys/dev/ath/if_ath_ahb.c head/sys/dev/ath/if_ath_pci.c head/sys/dev/ath/if_athvar.h Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Thu Feb 7 06:48:47 2013 (r246452) +++ head/sys/dev/ath/if_ath.c Thu Feb 7 07:50:16 2013 (r246453) @@ -2687,7 +2687,7 @@ ath_txq_qadd(struct ifnet *ifp, struct m struct mbuf *m; /* XXX recursive TX completion -> TX? */ - ATH_TX_UNLOCK_ASSERT(sc); + ATH_TX_IC_UNLOCK_ASSERT(sc); /* * We grab the node pointer, but we don't deref @@ -2749,7 +2749,7 @@ ath_txq_qadd(struct ifnet *ifp, struct m * into the driver. */ - ATH_TX_LOCK(sc); + ATH_TX_IC_LOCK(sc); /* * Throw the single frame onto the queue. @@ -2797,7 +2797,7 @@ ath_txq_qadd(struct ifnet *ifp, struct m m = m->m_nextpkt; } - ATH_TX_UNLOCK(sc); + ATH_TX_IC_UNLOCK(sc); return (0); bad: @@ -2825,13 +2825,13 @@ ath_txq_qflush(struct ifnet *ifp) TAILQ_INIT(&txlist); /* Grab lock */ - ATH_TX_LOCK(sc); + ATH_TX_IC_LOCK(sc); /* Copy everything out of sc_txbuf_list into txlist */ TAILQ_CONCAT(&txlist, &sc->sc_txbuf_list, bf_list); /* Unlock */ - ATH_TX_UNLOCK(sc); + ATH_TX_IC_UNLOCK(sc); /* Now, walk the list, freeing things */ while ((bf = TAILQ_FIRST(&txlist)) != NULL) { @@ -2879,16 +2879,9 @@ ath_txq_qrun(struct ifnet *ifp) */ /* Copy everything out of sc_txbuf_list into txlist */ - ATH_TX_LOCK(sc); + ATH_TX_IC_LOCK(sc); TAILQ_CONCAT(&txlist, &sc->sc_txbuf_list, bf_list); - ATH_TX_UNLOCK(sc); - - /* - * For now, the ath_tx_start() code sits behind the same lock; - * worry about serialising this in a taskqueue later. - */ - - ATH_TX_LOCK(sc); + ATH_TX_IC_UNLOCK(sc); /* * Attempt to transmit each frame. @@ -2899,6 +2892,7 @@ ath_txq_qrun(struct ifnet *ifp) * It would be nice to chain together TX fragments in this * way so they can be aborted together. */ + ATH_TX_LOCK(sc); TAILQ_FOREACH_SAFE(bf, &txlist, bf_list, bf_next) { /* * Clear, because we're going to reuse this Modified: head/sys/dev/ath/if_ath_ahb.c ============================================================================== --- head/sys/dev/ath/if_ath_ahb.c Thu Feb 7 06:48:47 2013 (r246452) +++ head/sys/dev/ath/if_ath_ahb.c Thu Feb 7 07:50:16 2013 (r246453) @@ -195,6 +195,7 @@ ath_ahb_attach(device_t dev) ATH_PCU_LOCK_INIT(sc); ATH_RX_LOCK_INIT(sc); ATH_TX_LOCK_INIT(sc); + ATH_TX_IC_LOCK_INIT(sc); ATH_TXSTATUS_LOCK_INIT(sc); error = ath_attach(AR9130_DEVID, sc); @@ -204,6 +205,7 @@ ath_ahb_attach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); + ATH_TX_IC_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); bus_dma_tag_destroy(sc->sc_dmat); @@ -247,6 +249,7 @@ ath_ahb_detach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); + ATH_TX_IC_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); Modified: head/sys/dev/ath/if_ath_pci.c ============================================================================== --- head/sys/dev/ath/if_ath_pci.c Thu Feb 7 06:48:47 2013 (r246452) +++ head/sys/dev/ath/if_ath_pci.c Thu Feb 7 07:50:16 2013 (r246453) @@ -251,6 +251,7 @@ ath_pci_attach(device_t dev) ATH_PCU_LOCK_INIT(sc); ATH_RX_LOCK_INIT(sc); ATH_TX_LOCK_INIT(sc); + ATH_TX_IC_LOCK_INIT(sc); ATH_TXSTATUS_LOCK_INIT(sc); error = ath_attach(pci_get_device(dev), sc); @@ -260,6 +261,7 @@ ath_pci_attach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); + ATH_TX_IC_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); bus_dma_tag_destroy(sc->sc_dmat); @@ -302,6 +304,7 @@ ath_pci_detach(device_t dev) ATH_TXSTATUS_LOCK_DESTROY(sc); ATH_PCU_LOCK_DESTROY(sc); ATH_RX_LOCK_DESTROY(sc); + ATH_TX_IC_LOCK_DESTROY(sc); ATH_TX_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); Modified: head/sys/dev/ath/if_athvar.h ============================================================================== --- head/sys/dev/ath/if_athvar.h Thu Feb 7 06:48:47 2013 (r246452) +++ head/sys/dev/ath/if_athvar.h Thu Feb 7 07:50:16 2013 (r246453) @@ -520,8 +520,10 @@ struct ath_softc { char sc_pcu_mtx_name[32]; struct mtx sc_rx_mtx; /* RX access mutex */ char sc_rx_mtx_name[32]; - struct mtx sc_tx_mtx; /* TX access mutex */ + struct mtx sc_tx_mtx; /* TX handling/comp mutex */ char sc_tx_mtx_name[32]; + struct mtx sc_tx_ic_mtx; /* TX queue mutex */ + char sc_tx_ic_mtx_name[32]; struct taskqueue *sc_tq; /* private task queue */ struct taskqueue *sc_tx_tq; /* private TX task queue */ struct ath_hal *sc_ah; /* Atheros HAL */ @@ -795,10 +797,8 @@ struct ath_softc { #define ATH_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED) /* - * The TX lock is non-reentrant and serialises the TX send operations. - * (ath_start(), ath_raw_xmit().) It doesn't yet serialise the TX - * completion operations; thus it can't be used (yet!) to protect - * hardware / software TXQ operations. + * The TX lock is non-reentrant and serialises the TX frame send + * and completion operations. */ #define ATH_TX_LOCK_INIT(_sc) do {\ snprintf((_sc)->sc_tx_mtx_name, \ @@ -817,6 +817,26 @@ struct ath_softc { MA_NOTOWNED) /* + * The IC TX lock is non-reentrant and serialises packet queuing from + * the upper layers. + */ +#define ATH_TX_IC_LOCK_INIT(_sc) do {\ + snprintf((_sc)->sc_tx_ic_mtx_name, \ + sizeof((_sc)->sc_tx_ic_mtx_name), \ + "%s IC TX lock", \ + device_get_nameunit((_sc)->sc_dev)); \ + mtx_init(&(_sc)->sc_tx_ic_mtx, (_sc)->sc_tx_ic_mtx_name, \ + NULL, MTX_DEF); \ + } while (0) +#define ATH_TX_IC_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_tx_ic_mtx) +#define ATH_TX_IC_LOCK(_sc) mtx_lock(&(_sc)->sc_tx_ic_mtx) +#define ATH_TX_IC_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_tx_ic_mtx) +#define ATH_TX_IC_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_ic_mtx, \ + MA_OWNED) +#define ATH_TX_IC_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_ic_mtx, \ + MA_NOTOWNED) + +/* * The PCU lock is non-recursive and should be treated as a spinlock. * Although currently the interrupt code is run in netisr context and * doesn't require this, this may change in the future.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302070750.r177oHiC058531>