summaryrefslogtreecommitdiffstats
path: root/sys/dev/tsec/if_tsec.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2009-05-30 15:14:44 +0000
committerattilio <attilio@FreeBSD.org>2009-05-30 15:14:44 +0000
commitb523608331b881784ac18a7dfcb65c7a679130b0 (patch)
tree073ce0f089e7f642e36b12a238c6d66778db53f5 /sys/dev/tsec/if_tsec.c
parentd03ca3acc6b07da900f12523e3d2560f84b538c4 (diff)
downloadFreeBSD-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/tsec/if_tsec.c')
-rw-r--r--sys/dev/tsec/if_tsec.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/dev/tsec/if_tsec.c b/sys/dev/tsec/if_tsec.c
index 7c11229..3676cfc 100644
--- a/sys/dev/tsec/if_tsec.c
+++ b/sys/dev/tsec/if_tsec.c
@@ -97,7 +97,7 @@ static int tsec_sysctl_ic_time(SYSCTL_HANDLER_ARGS);
static int tsec_sysctl_ic_count(SYSCTL_HANDLER_ARGS);
static void tsec_set_rxic(struct tsec_softc *sc);
static void tsec_set_txic(struct tsec_softc *sc);
-static void tsec_receive_intr_locked(struct tsec_softc *sc, int count);
+static int tsec_receive_intr_locked(struct tsec_softc *sc, int count);
static void tsec_transmit_intr_locked(struct tsec_softc *sc);
static void tsec_error_intr_locked(struct tsec_softc *sc, int count);
static void tsec_offload_setup(struct tsec_softc *sc);
@@ -857,16 +857,19 @@ tsec_setfilter(struct tsec_softc *sc)
#ifdef DEVICE_POLLING
static poll_handler_t tsec_poll;
-static void
+static int
tsec_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
uint32_t ie;
struct tsec_softc *sc = ifp->if_softc;
+ int rx_npkts;
+
+ rx_npkts = 0;
TSEC_GLOBAL_LOCK(sc);
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
TSEC_GLOBAL_UNLOCK(sc);
- return;
+ return (rx_npkts);
}
if (cmd == POLL_AND_CHECK_STATUS) {
@@ -881,9 +884,11 @@ tsec_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
TSEC_GLOBAL_TO_RECEIVE_LOCK(sc);
- tsec_receive_intr_locked(sc, count);
+ rx_npkts = tsec_receive_intr_locked(sc, count);
TSEC_RECEIVE_UNLOCK(sc);
+
+ return (rx_npkts);
}
#endif /* DEVICE_POLLING */
@@ -1248,7 +1253,7 @@ tsec_tick(void *arg)
*
* Loops at most count times if count is > 0, or until done if count < 0.
*/
-static void
+static int
tsec_receive_intr_locked(struct tsec_softc *sc, int count)
{
struct tsec_desc *rx_desc;
@@ -1257,7 +1262,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count)
struct mbuf *m;
device_t dev;
uint32_t i;
- int c;
+ int c, rx_npkts;
uint16_t flags;
TSEC_RECEIVE_LOCK_ASSERT(sc);
@@ -1265,6 +1270,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count)
ifp = sc->tsec_ifp;
rx_data = sc->rx_data;
dev = sc->dev;
+ rx_npkts = 0;
bus_dmamap_sync(sc->tsec_rx_dtag, sc->tsec_rx_dmap,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -1358,6 +1364,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count)
TSEC_RECEIVE_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
TSEC_RECEIVE_LOCK(sc);
+ rx_npkts++;
}
}
@@ -1373,6 +1380,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count)
* halted, and is harmless if already running.
*/
TSEC_WRITE(sc, TSEC_REG_RSTAT, TSEC_RSTAT_QHLT);
+ return (rx_npkts);
}
void
OpenPOWER on IntegriCloud