diff options
author | attilio <attilio@FreeBSD.org> | 2009-05-30 15:14:44 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2009-05-30 15:14:44 +0000 |
commit | b523608331b881784ac18a7dfcb65c7a679130b0 (patch) | |
tree | 073ce0f089e7f642e36b12a238c6d66778db53f5 /sys/dev/stge | |
parent | d03ca3acc6b07da900f12523e3d2560f84b538c4 (diff) | |
download | FreeBSD-src-b523608331b881784ac18a7dfcb65c7a679130b0.zip FreeBSD-src-b523608331b881784ac18a7dfcb65c7a679130b0.tar.gz |
When user_frac in the polling subsystem is low it is going to busy the
CPU for too long period than necessary. Additively, interfaces are kept
polled (in the tick) even if no more packets are available.
In order to avoid such situations a new generic mechanism can be
implemented in proactive way, keeping track of the time spent on any
packet and fragmenting the time for any tick, stopping the processing
as soon as possible.
In order to implement such mechanism, the polling handler needs to
change, returning the number of packets processed.
While the intended logic is not part of this patch, the polling KPI is
broken by this commit, adding an int return value and the new flag
IFCAP_POLLING_NOCOUNT (which will signal that the return value is
meaningless for the installed handler and checking should be skipped).
Bump __FreeBSD_version in order to signal such situation.
Reviewed by: emaste
Sponsored by: Sandvine Incorporated
Diffstat (limited to 'sys/dev/stge')
-rw-r--r-- | sys/dev/stge/if_stge.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/sys/dev/stge/if_stge.c b/sys/dev/stge/if_stge.c index e78ff25ab..0e12728 100644 --- a/sys/dev/stge/if_stge.c +++ b/sys/dev/stge/if_stge.c @@ -160,7 +160,7 @@ static void stge_link_task(void *, int); static void stge_intr(void *); static __inline int stge_tx_error(struct stge_softc *); static void stge_txeof(struct stge_softc *); -static void stge_rxeof(struct stge_softc *); +static int stge_rxeof(struct stge_softc *); static __inline void stge_discard_rxbuf(struct stge_softc *, int); static int stge_newbuf(struct stge_softc *, int); #ifndef __NO_STRICT_ALIGNMENT @@ -184,7 +184,7 @@ static void stge_dma_wait(struct stge_softc *); static void stge_init_tx_ring(struct stge_softc *); static int stge_init_rx_ring(struct stge_softc *); #ifdef DEVICE_POLLING -static void stge_poll(struct ifnet *, enum poll_cmd, int); +static int stge_poll(struct ifnet *, enum poll_cmd, int); #endif static void stge_setwol(struct stge_softc *); @@ -1772,7 +1772,7 @@ stge_fixup_rx(struct stge_softc *sc, struct mbuf *m) * * Helper; handle receive interrupts. */ -static void +static int stge_rxeof(struct stge_softc *sc) { struct ifnet *ifp; @@ -1780,10 +1780,11 @@ stge_rxeof(struct stge_softc *sc) struct mbuf *mp, *m; uint64_t status64; uint32_t status; - int cons, prog; + int cons, prog, rx_npkts; STGE_LOCK_ASSERT(sc); + rx_npkts = 0; ifp = sc->sc_ifp; bus_dmamap_sync(sc->sc_cdata.stge_rx_ring_tag, @@ -1901,6 +1902,7 @@ stge_rxeof(struct stge_softc *sc) /* Pass it on. */ (*ifp->if_input)(ifp, m); STGE_LOCK(sc); + rx_npkts++; STGE_RXCHAIN_RESET(sc); } @@ -1913,24 +1915,27 @@ stge_rxeof(struct stge_softc *sc) sc->sc_cdata.stge_rx_ring_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } + return (rx_npkts); } #ifdef DEVICE_POLLING -static void +static int stge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct stge_softc *sc; uint16_t status; + int rx_npkts; + rx_npkts = 0; sc = ifp->if_softc; STGE_LOCK(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { STGE_UNLOCK(sc); - return; + return (rx_npkts); } sc->sc_cdata.stge_rxcycles = count; - stge_rxeof(sc); + rx_npkts = stge_rxeof(sc); stge_txeof(sc); if (cmd == POLL_AND_CHECK_STATUS) { @@ -1954,6 +1959,7 @@ stge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) stge_start_locked(ifp); STGE_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ |