summaryrefslogtreecommitdiffstats
path: root/sys/dev/fxp
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/fxp
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/fxp')
-rw-r--r--sys/dev/fxp/if_fxp.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 0bddd17..c332552 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -217,7 +217,7 @@ static int fxp_resume(device_t dev);
static void fxp_intr(void *xsc);
static void fxp_rxcsum(struct fxp_softc *sc, struct ifnet *ifp,
struct mbuf *m, uint16_t status, int pos);
-static void fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp,
+static int fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp,
uint8_t statack, int count);
static void fxp_init(void *xsc);
static void fxp_init_body(struct fxp_softc *sc);
@@ -1619,16 +1619,17 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
#ifdef DEVICE_POLLING
static poll_handler_t fxp_poll;
-static void
+static int
fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
struct fxp_softc *sc = ifp->if_softc;
uint8_t statack;
+ int rx_npkts = 0;
FXP_LOCK(sc);
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
FXP_UNLOCK(sc);
- return;
+ return (rx_npkts);
}
statack = FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA |
@@ -1639,7 +1640,7 @@ fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
tmp = CSR_READ_1(sc, FXP_CSR_SCB_STATACK);
if (tmp == 0xff || tmp == 0) {
FXP_UNLOCK(sc);
- return; /* nothing to do */
+ return (rx_npkts); /* nothing to do */
}
tmp &= ~statack;
/* ack what we can */
@@ -1647,8 +1648,9 @@ fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, tmp);
statack |= tmp;
}
- fxp_intr_body(sc, ifp, statack, count);
+ rx_npkts = fxp_intr_body(sc, ifp, statack, count);
FXP_UNLOCK(sc);
+ return (rx_npkts);
}
#endif /* DEVICE_POLLING */
@@ -1805,7 +1807,7 @@ fxp_rxcsum(struct fxp_softc *sc, struct ifnet *ifp, struct mbuf *m,
m->m_pkthdr.csum_data = csum;
}
-static void
+static int
fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
int count)
{
@@ -1813,9 +1815,12 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
struct fxp_rx *rxp;
struct fxp_rfa *rfa;
int rnr = (statack & FXP_SCB_STATACK_RNR) ? 1 : 0;
+ int rx_npkts;
uint16_t status;
+ rx_npkts = 0;
FXP_LOCK_ASSERT(sc, MA_OWNED);
+
if (rnr)
sc->rnr++;
#ifdef DEVICE_POLLING
@@ -1852,7 +1857,7 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
* Just return if nothing happened on the receive side.
*/
if (!rnr && (statack & FXP_SCB_STATACK_FR) == 0)
- return;
+ return (rx_npkts);
/*
* Process receiver interrupts. If a no-resource (RNR)
@@ -1944,6 +1949,7 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
FXP_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
FXP_LOCK(sc);
+ rx_npkts++;
} else {
/* Reuse RFA and loaded DMA map. */
ifp->if_iqdrops++;
@@ -1957,6 +1963,7 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
sc->fxp_desc.rx_head->rx_addr);
fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
}
+ return (rx_npkts);
}
/*
OpenPOWER on IntegriCloud