Date: Tue, 14 Apr 2009 03:36:59 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r191038 - head/sys/dev/e1000 Message-ID: <200904140336.n3E3ax9n092979@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Tue Apr 14 03:36:59 2009 New Revision: 191038 URL: http://svn.freebsd.org/changeset/base/191038 Log: - define em_transmit and em_qflush - make buF_ring usage conditional but enabled by default Reviewed by: jfv Modified: head/sys/dev/e1000/if_em.c head/sys/dev/e1000/if_em.h Modified: head/sys/dev/e1000/if_em.c ============================================================================== --- head/sys/dev/e1000/if_em.c Tue Apr 14 03:17:44 2009 (r191037) +++ head/sys/dev/e1000/if_em.c Tue Apr 14 03:36:59 2009 (r191038) @@ -39,6 +39,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/buf_ring.h> #include <sys/bus.h> #include <sys/endian.h> #include <sys/kernel.h> @@ -897,6 +898,9 @@ em_detach(device_t dev) bus_generic_detach(dev); if_free(ifp); +#ifdef IFNET_BUF_RING + drbr_free(adapter->br, M_DEVBUF); +#endif em_free_transmit_structures(adapter); em_free_receive_structures(adapter); @@ -991,6 +995,110 @@ em_resume(device_t dev) * the packet is requeued. **********************************************************************/ +#ifdef IFNET_BUF_RING +static int +em_transmit_locked(struct ifnet *ifp, struct mbuf *m) +{ + struct adapter *adapter = ifp->if_softc; + int error; + + EM_TX_LOCK_ASSERT(adapter); + if (((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) + || (!adapter->link_active)) { + error = drbr_enqueue(ifp, adapter->br, m); + return (error); + } + + if (ADAPTER_RING_EMPTY(adapter) && + (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) { + if (em_xmit(adapter, &m)) { + if (m && (error = drbr_enqueue(ifp, adapter->br, m)) != 0) { + return (error); + } + } else{ + /* Send a copy of the frame to the BPF listener */ + ETHER_BPF_MTAP(ifp, m); + } + } else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0) + return (error); + + if (!ADAPTER_RING_EMPTY(adapter)) + em_start_locked(ifp); + + return (0); +} + +static int +em_transmit(struct ifnet *ifp, struct mbuf *m) +{ + + struct adapter *adapter = ifp->if_softc; + int error = 0; + + if(EM_TX_TRYLOCK(adapter)) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + error = em_transmit_locked(ifp, m); + EM_TX_UNLOCK(adapter); + } else + error = drbr_enqueue(ifp, adapter->br, m); + + return (error); +} + +static void +em_qflush(struct ifnet *ifp) +{ + struct mbuf *m; + struct adapter *adapter = (struct adapter *)ifp->if_softc; + + EM_TX_LOCK(adapter); + while ((m = buf_ring_dequeue_sc(adapter->br)) != NULL) + m_freem(m); + EM_TX_UNLOCK(adapter); +} + +static void +em_start_locked(struct ifnet *ifp) +{ + struct adapter *adapter = ifp->if_softc; + struct mbuf *m_head; + + EM_TX_LOCK_ASSERT(adapter); + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) + return; + if (!adapter->link_active) + return; + + while ((adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD) + && (!ADAPTER_RING_EMPTY(adapter))) { + + m_head = buf_ring_dequeue_sc(adapter->br); + if (m_head == NULL) + break; + /* + * Encapsulation can modify our pointer, and or make it + * NULL on failure. In that event, we can't requeue. + */ + if (em_xmit(adapter, &m_head)) { + if (m_head == NULL) + break; + break; + } + + /* Send a copy of the frame to the BPF listener */ + ETHER_BPF_MTAP(ifp, m_head); + + /* Set timeout in case hardware has problems transmitting. */ + adapter->watchdog_timer = EM_TX_TIMEOUT; + } + if ((adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + +} +#else static void em_start_locked(struct ifnet *ifp) { @@ -1030,6 +1138,8 @@ em_start_locked(struct ifnet *ifp) } } +#endif + static void em_start(struct ifnet *ifp) { @@ -1603,7 +1713,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd EM_TX_LOCK(adapter); em_txeof(adapter); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + if (!ADAPTER_RING_EMPTY(adapter)) em_start_locked(ifp); EM_TX_UNLOCK(adapter); } @@ -1658,7 +1768,7 @@ em_intr(void *arg) out: EM_CORE_UNLOCK(adapter); if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + !ADAPTER_RING_EMPTY(adapter)) em_start(ifp); } @@ -1697,7 +1807,7 @@ em_handle_rxtx(void *context, int pendin EM_TX_LOCK(adapter); em_txeof(adapter); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + if (!ADAPTER_RING_EMPTY(adapter)) em_start_locked(ifp); EM_TX_UNLOCK(adapter); } @@ -1853,9 +1963,15 @@ em_handle_tx(void *context, int pending) struct ifnet *ifp = adapter->ifp; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { +#ifdef IFNET_BUF_RING + if (!EM_TX_TRYLOCK(adapter)) + return; +#else EM_TX_LOCK(adapter); +#endif + em_txeof(adapter); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + if (!ADAPTER_RING_EMPTY(adapter)) em_start_locked(ifp); EM_TX_UNLOCK(adapter); } @@ -2075,22 +2191,14 @@ em_xmit(struct adapter *adapter, struct error = bus_dmamap_load_mbuf_sg(adapter->txtag, map, *m_headp, segs, &nsegs, BUS_DMA_NOWAIT); - if (error == ENOMEM) { - adapter->no_tx_dma_setup++; - return (error); - } else if (error != 0) { + if (error) { adapter->no_tx_dma_setup++; m_freem(*m_headp); *m_headp = NULL; return (error); } - } else if (error == ENOMEM) { - adapter->no_tx_dma_setup++; - return (error); } else if (error != 0) { adapter->no_tx_dma_setup++; - m_freem(*m_headp); - *m_headp = NULL; return (error); } @@ -2531,6 +2639,8 @@ em_local_timer(void *arg) EM_CORE_LOCK_ASSERT(adapter); + taskqueue_enqueue(adapter->tq, + &adapter->rxtx_task); em_update_link_status(adapter); em_update_stats_counters(adapter); @@ -3126,6 +3236,11 @@ em_setup_interface(device_t dev, struct ifp->if_capabilities = ifp->if_capenable = 0; +#ifdef IFNET_BUF_RING + ifp->if_transmit = em_transmit; + ifp->if_qflush = em_qflush; + adapter->br = buf_ring_alloc(2048, M_DEVBUF, M_WAITOK, &adapter->tx_mtx); +#endif if (adapter->hw.mac.type >= e1000_82543) { int version_cap; #if __FreeBSD_version < 700000 Modified: head/sys/dev/e1000/if_em.h ============================================================================== --- head/sys/dev/e1000/if_em.h Tue Apr 14 03:17:44 2009 (r191037) +++ head/sys/dev/e1000/if_em.h Tue Apr 14 03:36:59 2009 (r191038) @@ -36,6 +36,7 @@ #ifndef _EM_H_DEFINED_ #define _EM_H_DEFINED_ +#define IFNET_BUF_RING /* Tunables */ /* @@ -301,6 +302,9 @@ struct em_dma_alloc { /* Our adapter structure */ struct adapter { struct ifnet *ifp; +#ifdef IFNET_BUF_RING + struct buf_ring *br; +#endif struct e1000_hw hw; /* FreeBSD operating-system-specific structures. */ @@ -482,6 +486,7 @@ typedef struct _DESCRIPTOR_PAIR #define EM_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx) #define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx) #define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define EM_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx) #define EM_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx) #define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx) #define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) @@ -489,4 +494,9 @@ typedef struct _DESCRIPTOR_PAIR #define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED) #define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED) +#ifdef IFNET_BUF_RING +#define ADAPTER_RING_EMPTY(adapter) drbr_empty((adapter)->ifp, (adapter)->br) +#else +#define ADAPTER_RING_EMPTY(adapter) IFQ_DRV_IS_EMPTY(&((adapter)->ifp->if_snd)) +#endif #endif /* _EM_H_DEFINED_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904140336.n3E3ax9n092979>