Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 May 2009 15:14:44 +0000 (UTC)
From:      Attilio Rao <attilio@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r193096 - in head/sys: arm/xscale/ixp425 dev/bge dev/dc dev/e1000 dev/firewire dev/fxp dev/ixgb dev/lmc dev/mge dev/nfe dev/re dev/sf dev/sis dev/smc dev/ste dev/stge dev/tsec dev/vge d...
Message-ID:  <200905301514.n4UFEi5F011371@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: attilio
Date: Sat May 30 15:14:44 2009
New Revision: 193096
URL: http://svn.freebsd.org/changeset/base/193096

Log:
  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

Modified:
  head/sys/arm/xscale/ixp425/if_npe.c
  head/sys/arm/xscale/ixp425/ixp425_qmgr.c
  head/sys/arm/xscale/ixp425/ixp425_qmgr.h
  head/sys/dev/bge/if_bge.c
  head/sys/dev/dc/if_dc.c
  head/sys/dev/e1000/if_em.c
  head/sys/dev/firewire/if_fwe.c
  head/sys/dev/firewire/if_fwip.c
  head/sys/dev/fxp/if_fxp.c
  head/sys/dev/ixgb/if_ixgb.c
  head/sys/dev/lmc/if_lmc.c
  head/sys/dev/mge/if_mge.c
  head/sys/dev/nfe/if_nfe.c
  head/sys/dev/re/if_re.c
  head/sys/dev/sf/if_sf.c
  head/sys/dev/sis/if_sis.c
  head/sys/dev/smc/if_smc.c
  head/sys/dev/ste/if_ste.c
  head/sys/dev/stge/if_stge.c
  head/sys/dev/tsec/if_tsec.c
  head/sys/dev/vge/if_vge.c
  head/sys/dev/vr/if_vr.c
  head/sys/dev/xl/if_xl.c
  head/sys/net/if.h
  head/sys/net/if_var.h
  head/sys/pci/if_rl.c
  head/sys/sys/param.h

Modified: head/sys/arm/xscale/ixp425/if_npe.c
==============================================================================
--- head/sys/arm/xscale/ixp425/if_npe.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/arm/xscale/ixp425/if_npe.c	Sat May 30 15:14:44 2009	(r193096)
@@ -229,7 +229,7 @@ static void	npe_getmac(struct npe_softc 
 static void	npe_txdone(int qid, void *arg);
 static int	npe_rxbuf_init(struct npe_softc *, struct npebuf *,
 			struct mbuf *);
-static void	npe_rxdone(int qid, void *arg);
+static int	npe_rxdone(int qid, void *arg);
 static void	npeinit(void *);
 static void	npestart_locked(struct ifnet *);
 static void	npestart(struct ifnet *);
@@ -777,7 +777,7 @@ npe_activate(device_t dev)
 	 */
 	sc->rx_qid = npeconfig[sc->sc_npeid].rx_qid;
 	ixpqmgr_qconfig(sc->rx_qid, npe_rxbuf, 0,  1,
-		IX_QMGR_Q_SOURCE_ID_NOT_E, npe_rxdone, sc);
+		IX_QMGR_Q_SOURCE_ID_NOT_E, (qconfig_hand_t *)npe_rxdone, sc);
 	sc->rx_freeqid = npeconfig[sc->sc_npeid].rx_freeqid;
 	ixpqmgr_qconfig(sc->rx_freeqid,	npe_rxbuf, 0, npe_rxbuf/2, 0, NULL, sc);
 	/*
@@ -1091,7 +1091,7 @@ npe_rxbuf_init(struct npe_softc *sc, str
  * from the hardware queue and pass the frames up the
  * stack. Pass the rx buffers to the free list.
  */
-static void
+static int
 npe_rxdone(int qid, void *arg)
 {
 #define	P2V(a, dma) \
@@ -1099,6 +1099,7 @@ npe_rxdone(int qid, void *arg)
 	struct npe_softc *sc = arg;
 	struct npedma *dma = &sc->rxdma;
 	uint32_t entry;
+	int rx_npkts = 0;
 
 	while (ixpqmgr_qread(qid, &entry) == 0) {
 		struct npebuf *npe = P2V(NPE_QM_Q_ADDR(entry), dma);
@@ -1132,6 +1133,7 @@ npe_rxdone(int qid, void *arg)
 
 			ifp->if_ipackets++;
 			ifp->if_input(ifp, mrx);
+			rx_npkts++;
 		} else {
 			/* discard frame and re-use mbuf */
 			m = npe->ix_m;
@@ -1143,19 +1145,22 @@ npe_rxdone(int qid, void *arg)
 			/* XXX should not happen */
 		}
 	}
+	return (rx_npkts);
 #undef P2V
 }
 
 #ifdef DEVICE_POLLING
-static void
+static int
 npe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct npe_softc *sc = ifp->if_softc;
+	int rx_npkts = 0;
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		npe_rxdone(sc->rx_qid, sc);
+		rx_npkts = npe_rxdone(sc->rx_qid, sc);
 		npe_txdone(sc->tx_doneqid, sc);	/* XXX polls both NPE's */
 	}
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 

Modified: head/sys/arm/xscale/ixp425/ixp425_qmgr.c
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425_qmgr.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/arm/xscale/ixp425/ixp425_qmgr.c	Sat May 30 15:14:44 2009	(r193096)
@@ -338,7 +338,7 @@ ixpqmgr_detach(device_t dev)
 
 int
 ixpqmgr_qconfig(int qId, int qEntries, int ne, int nf, int srcSel,
-    void (*cb)(int, void *), void *cbarg)
+    qconfig_hand_t *cb, void *cbarg)
 {
 	struct ixpqmgr_softc *sc = ixpqmgr_sc;
 	struct qmgrInfo *qi = &sc->qinfo[qId];

Modified: head/sys/arm/xscale/ixp425/ixp425_qmgr.h
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425_qmgr.h	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/arm/xscale/ixp425/ixp425_qmgr.h	Sat May 30 15:14:44 2009	(r193096)
@@ -229,8 +229,10 @@
 #define IX_QMGR_ENTRY2_OFFSET 1
 #define IX_QMGR_ENTRY4_OFFSET 3
 
+typedef void qconfig_hand_t(int, void *);
+
 int	ixpqmgr_qconfig(int qId, int qSizeInWords, int ne, int nf, int srcSel,
-	    void (*cb)(int, void *), void *cbarg);
+	    qconfig_hand_t *cb, void *cbarg);
 int	ixpqmgr_qwrite(int qId, uint32_t entry);
 int	ixpqmgr_qread(int qId, uint32_t *entry);
 int	ixpqmgr_qreadm(int qId, uint32_t n, uint32_t *p);

Modified: head/sys/dev/bge/if_bge.c
==============================================================================
--- head/sys/dev/bge/if_bge.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/bge/if_bge.c	Sat May 30 15:14:44 2009	(r193096)
@@ -332,7 +332,7 @@ static int bge_get_eaddr_eeprom(struct b
 static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
 
 static void bge_txeof(struct bge_softc *);
-static void bge_rxeof(struct bge_softc *);
+static int bge_rxeof(struct bge_softc *);
 
 static void bge_asf_driver_up (struct bge_softc *);
 static void bge_tick(void *);
@@ -390,7 +390,7 @@ static int bge_miibus_readreg(device_t, 
 static int bge_miibus_writereg(device_t, int, int, int);
 static void bge_miibus_statchg(device_t);
 #ifdef DEVICE_POLLING
-static void bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+static int bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
 #endif
 
 #define	BGE_RESET_START 1
@@ -3050,18 +3050,18 @@ bge_reset(struct bge_softc *sc)
  * 2) the frame is from the standard receive ring
  */
 
-static void
+static int
 bge_rxeof(struct bge_softc *sc)
 {
 	struct ifnet *ifp;
-	int stdcnt = 0, jumbocnt = 0;
+	int rx_npkts = 0, stdcnt = 0, jumbocnt = 0;
 
 	BGE_LOCK_ASSERT(sc);
 
 	/* Nothing to do. */
 	if (sc->bge_rx_saved_considx ==
 	    sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx)
-		return;
+		return (rx_npkts);
 
 	ifp = sc->bge_ifp;
 
@@ -3193,6 +3193,7 @@ bge_rxeof(struct bge_softc *sc)
 		BGE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		BGE_LOCK(sc);
+		rk_npkts++;
 
 		if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 			return;
@@ -3219,6 +3220,7 @@ bge_rxeof(struct bge_softc *sc)
 	if (BGE_IS_5705_PLUS(sc))
 		ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS);
 #endif
+	return (rx_npkts);
 }
 
 static void
@@ -3271,16 +3273,17 @@ bge_txeof(struct bge_softc *sc)
 }
 
 #ifdef DEVICE_POLLING
-static void
+static int
 bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct bge_softc *sc = ifp->if_softc;
 	uint32_t statusword;
-	
+	int rx_npkts = 0;
+
 	BGE_LOCK(sc);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		BGE_UNLOCK(sc);
-		return;
+		return (rx_npkts);
 	}
 
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
@@ -3303,7 +3306,7 @@ bge_poll(struct ifnet *ifp, enum poll_cm
 			bge_link_upd(sc);
 
 	sc->rxcycles = count;
-	bge_rxeof(sc);
+	rx_npkts = bge_rxeof(sc);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		BGE_UNLOCK(sc);
 		return;
@@ -3313,6 +3316,7 @@ bge_poll(struct ifnet *ifp, enum poll_cm
 		bge_start_locked(ifp);
 
 	BGE_UNLOCK(sc);
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 

Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/dc/if_dc.c	Sat May 30 15:14:44 2009	(r193096)
@@ -236,7 +236,7 @@ static int dc_newbuf(struct dc_softc *, 
 static int dc_encap(struct dc_softc *, struct mbuf **);
 static void dc_pnic_rx_bug_war(struct dc_softc *, int);
 static int dc_rx_resync(struct dc_softc *);
-static void dc_rxeof(struct dc_softc *);
+static int dc_rxeof(struct dc_softc *);
 static void dc_txeof(struct dc_softc *);
 static void dc_tick(void *);
 static void dc_tx_underrun(struct dc_softc *);
@@ -2640,19 +2640,21 @@ dc_rx_resync(struct dc_softc *sc)
  * A frame has been uploaded: pass the resulting mbuf chain up to
  * the higher level protocols.
  */
-static void
+static int
 dc_rxeof(struct dc_softc *sc)
 {
 	struct mbuf *m, *m0;
 	struct ifnet *ifp;
 	struct dc_desc *cur_rx;
-	int i, total_len = 0;
+	int i, total_len, rx_npkts;
 	u_int32_t rxstat;
 
 	DC_LOCK_ASSERT(sc);
 
 	ifp = sc->dc_ifp;
 	i = sc->dc_cdata.dc_rx_prod;
+	total_len = 0;
+	rx_npkts = 0;
 
 	bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap, BUS_DMASYNC_POSTREAD);
 	while (!(le32toh(sc->dc_ldata->dc_rx_list[i].dc_status) &
@@ -2706,7 +2708,7 @@ dc_rxeof(struct dc_softc *sc)
 					continue;
 				} else {
 					dc_init_locked(sc);
-					return;
+					return (rx_npkts);
 				}
 			}
 		}
@@ -2745,9 +2747,11 @@ dc_rxeof(struct dc_softc *sc)
 		DC_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		DC_LOCK(sc);
+		rx_npkts++;
 	}
 
 	sc->dc_cdata.dc_rx_prod = i;
+	return (rx_npkts);
 }
 
 /*
@@ -2989,20 +2993,21 @@ dc_tx_underrun(struct dc_softc *sc)
 #ifdef DEVICE_POLLING
 static poll_handler_t dc_poll;
 
-static void
+static int
 dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct dc_softc *sc = ifp->if_softc;
+	int rx_npkts = 0;
 
 	DC_LOCK(sc);
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		DC_UNLOCK(sc);
-		return;
+		return (rx_npkts);
 	}
 
 	sc->rxcycles = count;
-	dc_rxeof(sc);
+	rx_npkts = dc_rxeof(sc);
 	dc_txeof(sc);
 	if (!IFQ_IS_EMPTY(&ifp->if_snd) &&
 	    !(ifp->if_drv_flags & IFF_DRV_OACTIVE))
@@ -3017,7 +3022,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd
 			DC_ISR_BUS_ERR);
 		if (!status) {
 			DC_UNLOCK(sc);
-			return;
+			return (rx_npkts);
 		}
 		/* ack what we have */
 		CSR_WRITE_4(sc, DC_ISR, status);
@@ -3043,6 +3048,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd
 		}
 	}
 	DC_UNLOCK(sc);
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/e1000/if_em.c	Sat May 30 15:14:44 2009	(r193096)
@@ -261,7 +261,7 @@ static void	em_txeof(struct adapter *);
 static void	em_tx_purge(struct adapter *);
 static int	em_allocate_receive_structures(struct adapter *);
 static int	em_allocate_transmit_structures(struct adapter *);
-static int	em_rxeof(struct adapter *, int);
+static int	em_rxeof(struct adapter *, int, int *);
 #ifndef __NO_STRICT_ALIGNMENT
 static int	em_fixup_rx(struct adapter *);
 #endif
@@ -1653,16 +1653,20 @@ em_init(void *arg)
  *  Legacy polling routine  
  *
  *********************************************************************/
-static void
+static int
 em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
-	struct adapter *adapter = ifp->if_softc;
+	struct adapter *adapter;
 	u32		reg_icr;
+	int		rx_npkts;
+
+	adapter = ifp->if_softc;
+	rx_npkts = 0;
 
 	EM_CORE_LOCK(adapter);
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		EM_CORE_UNLOCK(adapter);
-		return;
+		return (rx_npkts);
 	}
 
 	if (cmd == POLL_AND_CHECK_STATUS) {
@@ -1677,7 +1681,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd
 	}
 	EM_CORE_UNLOCK(adapter);
 
-	em_rxeof(adapter, count);
+	em_rxeof(adapter, count, &rx_npkts);
 
 	EM_TX_LOCK(adapter);
 	em_txeof(adapter);
@@ -1685,6 +1689,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd
 	if (!ADAPTER_RING_EMPTY(adapter))
 		em_start_locked(ifp);
 	EM_TX_UNLOCK(adapter);
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 
@@ -1718,7 +1723,7 @@ em_intr(void *arg)
 
 	EM_TX_LOCK(adapter);
 	em_txeof(adapter);
-	em_rxeof(adapter, -1);
+	em_rxeof(adapter, -1, NULL);
 	em_txeof(adapter);
 	EM_TX_UNLOCK(adapter);
 
@@ -1771,7 +1776,7 @@ em_handle_rxtx(void *context, int pendin
 
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		if (em_rxeof(adapter, adapter->rx_process_limit) != 0)
+		if (em_rxeof(adapter, adapter->rx_process_limit, NULL) != 0)
 			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
 		EM_TX_LOCK(adapter);
 		em_txeof(adapter);
@@ -1882,7 +1887,7 @@ em_msix_rx(void *arg)
 
 	++adapter->rx_irq;
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) &&
-	    (em_rxeof(adapter, adapter->rx_process_limit) != 0))
+	    (em_rxeof(adapter, adapter->rx_process_limit, NULL) != 0))
 		taskqueue_enqueue(adapter->tq, &adapter->rx_task);
 	/* Reenable this interrupt */
 	E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_RX);
@@ -1920,7 +1925,7 @@ em_handle_rx(void *context, int pending)
 	struct ifnet	*ifp = adapter->ifp;
 
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) &&
-	    (em_rxeof(adapter, adapter->rx_process_limit) != 0))
+	    (em_rxeof(adapter, adapter->rx_process_limit, NULL) != 0))
 		taskqueue_enqueue(adapter->tq, &adapter->rx_task);
 
 }
@@ -4461,23 +4466,26 @@ em_free_receive_structures(struct adapte
  *
  *********************************************************************/
 static int
-em_rxeof(struct adapter *adapter, int count)
+em_rxeof(struct adapter *adapter, int count, int *rx_npktsp)
 {
 	struct ifnet	*ifp = adapter->ifp;;
 	struct mbuf	*mp;
 	u8		status, accept_frame = 0, eop = 0;
 	u16 		len, desc_len, prev_len_adj;
-	int		i;
+	int		i, rx_npkts;
 	struct e1000_rx_desc   *current_desc;
 
 	EM_RX_LOCK(adapter);
 	i = adapter->next_rx_desc_to_check;
+	rx_npkts = 0;
 	current_desc = &adapter->rx_desc_base[i];
 	bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
 	    BUS_DMASYNC_POSTREAD);
 
 	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
 		EM_RX_UNLOCK(adapter);
+		if (rx_npktsp != NULL)
+			*rx_npktsp = rx_npkts;
 		return (0);
 	}
 
@@ -4626,6 +4634,7 @@ discard:
 			EM_RX_UNLOCK(adapter);
 			(*ifp->if_input)(ifp, m);
 			EM_RX_LOCK(adapter);
+			rx_npkts++;
 			i = adapter->next_rx_desc_to_check;
 		}
 		current_desc = &adapter->rx_desc_base[i];
@@ -4637,6 +4646,8 @@ discard:
 		i = adapter->num_rx_desc - 1;
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
 	EM_RX_UNLOCK(adapter);
+	if (rx_npktsp != NULL)
+		*rx_npktsp = rx_npkts;
 	if (!((current_desc->status) & E1000_RXD_STAT_DD))
 		return (0);
 

Modified: head/sys/dev/firewire/if_fwe.c
==============================================================================
--- head/sys/dev/firewire/if_fwe.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/firewire/if_fwe.c	Sat May 30 15:14:44 2009	(r193096)
@@ -105,18 +105,19 @@ TUNABLE_INT("hw.firewire.fwe.rx_queue_le
 #ifdef DEVICE_POLLING
 static poll_handler_t fwe_poll;
 
-static void
+static int
 fwe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct fwe_softc *fwe;
 	struct firewire_comm *fc;
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
-		return;
+		return (0);
 
 	fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe;
 	fc = fwe->fd.fc;
 	fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
+	return (0);
 }
 #endif /* DEVICE_POLLING */
 
@@ -455,6 +456,7 @@ fwe_ioctl(struct ifnet *ifp, u_long cmd,
 				/* Disable interrupts */
 				fc->set_intr(fc, 0);
 				ifp->if_capenable |= IFCAP_POLLING;
+				ifp->if_capenable |= IFCAP_POLLING_NOCOUNT;
 				return (error);
 			}
 			if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
@@ -463,6 +465,7 @@ fwe_ioctl(struct ifnet *ifp, u_long cmd,
 				/* Enable interrupts. */
 				fc->set_intr(fc, 1);
 				ifp->if_capenable &= ~IFCAP_POLLING;
+				ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT;
 				return (error);
 			}
 		    }

Modified: head/sys/dev/firewire/if_fwip.c
==============================================================================
--- head/sys/dev/firewire/if_fwip.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/firewire/if_fwip.c	Sat May 30 15:14:44 2009	(r193096)
@@ -112,18 +112,19 @@ TUNABLE_INT("hw.firewire.fwip.rx_queue_l
 #ifdef DEVICE_POLLING
 static poll_handler_t fwip_poll;
 
-static void
+static int
 fwip_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct fwip_softc *fwip;
 	struct firewire_comm *fc;
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
-		return;
+		return (0);
 
 	fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
 	fc = fwip->fd.fc;
 	fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
+	return (0);
 }
 #endif /* DEVICE_POLLING */
 
@@ -436,7 +437,8 @@ fwip_ioctl(struct ifnet *ifp, u_long cmd
 				return(error);
 			/* Disable interrupts */
 			fc->set_intr(fc, 0);
-			ifp->if_capenable |= IFCAP_POLLING;
+			ifp->if_capenable |= IFCAP_POLLING |
+			    IFCAP_POLLING_NOCOUNT;
 			return (error);
 			
 		}
@@ -446,6 +448,7 @@ fwip_ioctl(struct ifnet *ifp, u_long cmd
 			/* Enable interrupts. */
 			fc->set_intr(fc, 1);
 			ifp->if_capenable &= ~IFCAP_POLLING;
+			ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT;
 			return (error);
 		}
 	    }

Modified: head/sys/dev/fxp/if_fxp.c
==============================================================================
--- head/sys/dev/fxp/if_fxp.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/fxp/if_fxp.c	Sat May 30 15:14:44 2009	(r193096)
@@ -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 m
 #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_cm
 		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_cm
 			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 
 	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, stru
 	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, stru
 	 * 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, stru
 			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, stru
 		    sc->fxp_desc.rx_head->rx_addr);
 		fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
 	}
+	return (rx_npkts);
 }
 
 /*

Modified: head/sys/dev/ixgb/if_ixgb.c
==============================================================================
--- head/sys/dev/ixgb/if_ixgb.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/ixgb/if_ixgb.c	Sat May 30 15:14:44 2009	(r193096)
@@ -121,7 +121,7 @@ static void     ixgb_update_stats_counte
 static void     ixgb_clean_transmit_interrupts(struct adapter *);
 static int      ixgb_allocate_receive_structures(struct adapter *);
 static int      ixgb_allocate_transmit_structures(struct adapter *);
-static void     ixgb_process_receive_interrupts(struct adapter *, int);
+static int      ixgb_process_receive_interrupts(struct adapter *, int);
 static void 
 ixgb_receive_checksum(struct adapter *,
 		      struct ixgb_rx_desc * rx_desc,
@@ -748,11 +748,12 @@ ixgb_init(void *arg)
 }
 
 #ifdef DEVICE_POLLING
-static void
+static int
 ixgb_poll_locked(struct ifnet * ifp, enum poll_cmd cmd, int count)
 {
 	struct adapter *adapter = ifp->if_softc;
 	u_int32_t       reg_icr;
+	int		rx_npkts;
 
 	IXGB_LOCK_ASSERT(adapter);
 
@@ -766,22 +767,25 @@ ixgb_poll_locked(struct ifnet * ifp, enu
 			    adapter);
 		}
 	}
-	ixgb_process_receive_interrupts(adapter, count);
+	rx_npkts = ixgb_process_receive_interrupts(adapter, count);
 	ixgb_clean_transmit_interrupts(adapter);
 
 	if (ifp->if_snd.ifq_head != NULL)
 		ixgb_start_locked(ifp);
+	return (rx_npkts);
 }
 
-static void
+static int
 ixgb_poll(struct ifnet * ifp, enum poll_cmd cmd, int count)
 {
 	struct adapter *adapter = ifp->if_softc;
+	int rx_npkts = 0;
 
 	IXGB_LOCK(adapter);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-		ixgb_poll_locked(ifp, cmd, count);
+		rx_npkts = ixgb_poll_locked(ifp, cmd, count);
 	IXGB_UNLOCK(adapter);
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 
@@ -2065,7 +2069,7 @@ ixgb_free_receive_structures(struct adap
  *  count < 0.
  *
  *********************************************************************/
-static void
+static int
 ixgb_process_receive_interrupts(struct adapter * adapter, int count)
 {
 	struct ifnet   *ifp;
@@ -2079,6 +2083,7 @@ ixgb_process_receive_interrupts(struct a
 	int             i;
 	int             next_to_use = 0;
 	int             eop_desc;
+	int		rx_npkts = 0;
 	/* Pointer to the receive descriptor being examined. */
 	struct ixgb_rx_desc *current_desc;
 
@@ -2094,7 +2099,7 @@ ixgb_process_receive_interrupts(struct a
 #ifdef _SV_
 		adapter->no_pkts_avail++;
 #endif
-		return;
+		return (rx_npkts);
 	}
 	while ((current_desc->status & IXGB_RX_DESC_STATUS_DD) && (count != 0)) {
 
@@ -2168,6 +2173,7 @@ ixgb_process_receive_interrupts(struct a
 					IXGB_UNLOCK(adapter);
 					(*ifp->if_input) (ifp, adapter->fmp);
 					IXGB_LOCK(adapter);
+					rx_npkts++;
 				}
 #endif
 				adapter->fmp = NULL;
@@ -2239,7 +2245,7 @@ ixgb_process_receive_interrupts(struct a
 	/* Advance the IXGB's Receive Queue #0  "Tail Pointer" */
 	IXGB_WRITE_REG(&adapter->hw, RDT, next_to_use);
 
-	return;
+	return (rx_npkts);
 }
 
 /*********************************************************************

Modified: head/sys/dev/lmc/if_lmc.c
==============================================================================
--- head/sys/dev/lmc/if_lmc.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/lmc/if_lmc.c	Sat May 30 15:14:44 2009	(r193096)
@@ -3960,7 +3960,7 @@ user_interrupt(softc_t *sc, int check_st
 # if (defined(__FreeBSD__) && defined(DEVICE_POLLING))
 
 /* Service the card from the kernel idle loop without interrupts. */
-static void
+static int
 fbsd_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
   {
   softc_t *sc = IFP2SC(ifp);
@@ -4828,6 +4828,7 @@ setup_ifnet(struct ifnet *ifp)
 
 # if (defined(__FreeBSD__) && defined(DEVICE_POLLING))
   ifp->if_capabilities |= IFCAP_POLLING;
+  ifp->if_capenable    |= IFCAP_POLLING_NOCOUNT;
 # if (__FreeBSD_version < 500000)
   ifp->if_capenable    |= IFCAP_POLLING;
 # endif

Modified: head/sys/dev/mge/if_mge.c
==============================================================================
--- head/sys/dev/mge/if_mge.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/mge/if_mge.c	Sat May 30 15:14:44 2009	(r193096)
@@ -106,7 +106,7 @@ static void mge_ver_params(struct mge_so
 
 static void mge_intrs_ctrl(struct mge_softc *sc, int enable);
 static void mge_intr_rx(void *arg);
-static void mge_intr_rx_locked(struct mge_softc *sc, int count);
+static int mge_intr_rx_locked(struct mge_softc *sc, int count);
 static void mge_intr_tx(void *arg);
 static void mge_intr_tx_locked(struct mge_softc *sc);
 static void mge_intr_misc(void *arg);
@@ -569,17 +569,18 @@ mge_reinit_rx(struct mge_softc *sc)
 #ifdef DEVICE_POLLING
 static poll_handler_t mge_poll;
 
-static void
+static int
 mge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct mge_softc *sc = ifp->if_softc;
 	uint32_t int_cause, int_cause_ext;
+	int rx_npkts = 0;
 
 	MGE_GLOBAL_LOCK(sc);
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		MGE_GLOBAL_UNLOCK(sc);
-		return;
+		return (rx_npkts);
 	}
 
 	if (cmd == POLL_AND_CHECK_STATUS) {
@@ -597,9 +598,10 @@ mge_poll(struct ifnet *ifp, enum poll_cm
 	}
 
 	mge_intr_tx_locked(sc);
-	mge_intr_rx_locked(sc, count);
+	rx_npkts = mge_intr_rx_locked(sc, count);
 
 	MGE_GLOBAL_UNLOCK(sc);
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 
@@ -1013,7 +1015,7 @@ mge_intr_rx(void *arg) {
 }
 
 
-static void
+static int
 mge_intr_rx_locked(struct mge_softc *sc, int count)
 {
 	struct ifnet *ifp = sc->ifp;
@@ -1021,6 +1023,7 @@ mge_intr_rx_locked(struct mge_softc *sc,
 	uint16_t bufsize;
 	struct mge_desc_wrapper* dw;
 	struct mbuf *mb;
+	int rx_npkts = 0;
 
 	MGE_RECEIVE_LOCK_ASSERT(sc);
 
@@ -1059,6 +1062,7 @@ mge_intr_rx_locked(struct mge_softc *sc,
 			MGE_RECEIVE_UNLOCK(sc);
 			(*ifp->if_input)(ifp, mb);
 			MGE_RECEIVE_LOCK(sc);
+			rx_npkts++;
 		}
 
 		dw->mge_desc->byte_count = 0;
@@ -1071,7 +1075,7 @@ mge_intr_rx_locked(struct mge_softc *sc,
 			count -= 1;
 	}
 
-	return;
+	return (rx_npkts);
 }
 
 static void

Modified: head/sys/dev/nfe/if_nfe.c
==============================================================================
--- head/sys/dev/nfe/if_nfe.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/nfe/if_nfe.c	Sat May 30 15:14:44 2009	(r193096)
@@ -93,8 +93,8 @@ static __inline void nfe_discard_rxbuf(s
 static __inline void nfe_discard_jrxbuf(struct nfe_softc *, int);
 static int nfe_newbuf(struct nfe_softc *, int);
 static int nfe_jnewbuf(struct nfe_softc *, int);
-static int  nfe_rxeof(struct nfe_softc *, int);
-static int  nfe_jrxeof(struct nfe_softc *, int);
+static int  nfe_rxeof(struct nfe_softc *, int, int *);
+static int  nfe_jrxeof(struct nfe_softc *, int, int *);
 static void nfe_txeof(struct nfe_softc *);
 static int  nfe_encap(struct nfe_softc *, struct mbuf **);
 static void nfe_setmulti(struct nfe_softc *);
@@ -1551,23 +1551,24 @@ nfe_free_tx_ring(struct nfe_softc *sc, s
 static poll_handler_t nfe_poll;
 
 
-static void
+static int
 nfe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct nfe_softc *sc = ifp->if_softc;
 	uint32_t r;
+	int rx_npkts = 0;
 
 	NFE_LOCK(sc);
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		NFE_UNLOCK(sc);
-		return;
+		return (rx_npkts);
 	}
 
 	if (sc->nfe_framesize > MCLBYTES - ETHER_HDR_LEN)
-		nfe_jrxeof(sc, count);
+		rx_npkts = nfe_jrxeof(sc, count, &rx_npkts);
 	else
-		nfe_rxeof(sc, count);
+		rx_npkts = nfe_rxeof(sc, count, &rx_npkts);
 	nfe_txeof(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 		taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_tx_task);
@@ -1575,7 +1576,7 @@ nfe_poll(struct ifnet *ifp, enum poll_cm
 	if (cmd == POLL_AND_CHECK_STATUS) {
 		if ((r = NFE_READ(sc, sc->nfe_irq_status)) == 0) {
 			NFE_UNLOCK(sc);
-			return;
+			return (rx_npkts);
 		}
 		NFE_WRITE(sc, sc->nfe_irq_status, r);
 
@@ -1586,6 +1587,7 @@ nfe_poll(struct ifnet *ifp, enum poll_cm
 		}
 	}
 	NFE_UNLOCK(sc);
+	return (rx_npkts);
 }
 #endif /* DEVICE_POLLING */
 
@@ -1826,9 +1828,9 @@ nfe_int_task(void *arg, int pending)
 	domore = 0;
 	/* check Rx ring */
 	if (sc->nfe_framesize > MCLBYTES - ETHER_HDR_LEN)
-		domore = nfe_jrxeof(sc, sc->nfe_process_limit);
+		domore = nfe_jrxeof(sc, sc->nfe_process_limit, NULL);
 	else
-		domore = nfe_rxeof(sc, sc->nfe_process_limit);
+		domore = nfe_rxeof(sc, sc->nfe_process_limit, NULL);
 	/* check Tx ring */
 	nfe_txeof(sc);
 
@@ -2015,7 +2017,7 @@ nfe_jnewbuf(struct nfe_softc *sc, int id
 
 
 static int
-nfe_rxeof(struct nfe_softc *sc, int count)
+nfe_rxeof(struct nfe_softc *sc, int count, int *rx_npktsp)
 {
 	struct ifnet *ifp = sc->nfe_ifp;
 	struct nfe_desc32 *desc32;
@@ -2023,9 +2025,10 @@ nfe_rxeof(struct nfe_softc *sc, int coun
 	struct nfe_rx_data *data;
 	struct mbuf *m;
 	uint16_t flags;
-	int len, prog;
+	int len, prog, rx_npkts;
 	uint32_t vtag = 0;
 
+	rx_npkts = 0;
 	NFE_LOCK_ASSERT(sc);
 
 	bus_dmamap_sync(sc->rxq.rx_desc_tag, sc->rxq.rx_desc_map,
@@ -2115,18 +2118,21 @@ nfe_rxeof(struct nfe_softc *sc, int coun
 		NFE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		NFE_LOCK(sc);
+		rx_npkts++;
 	}
 
 	if (prog > 0)
 		bus_dmamap_sync(sc->rxq.rx_desc_tag, sc->rxq.rx_desc_map,
 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
+	if (rx_npktsp != NULL)
+		*rx_npktsp = rx_npkts;
 	return (count > 0 ? 0 : EAGAIN);
 }
 
 
 static int
-nfe_jrxeof(struct nfe_softc *sc, int count)
+nfe_jrxeof(struct nfe_softc *sc, int count, int *rx_npktsp)
 {
 	struct ifnet *ifp = sc->nfe_ifp;
 	struct nfe_desc32 *desc32;
@@ -2134,9 +2140,10 @@ nfe_jrxeof(struct nfe_softc *sc, int cou
 	struct nfe_rx_data *data;
 	struct mbuf *m;
 	uint16_t flags;
-	int len, prog;
+	int len, prog, rx_npkts;
 	uint32_t vtag = 0;
 
+	rx_npkts = 0;
 	NFE_LOCK_ASSERT(sc);
 
 	bus_dmamap_sync(sc->jrxq.jrx_desc_tag, sc->jrxq.jrx_desc_map,
@@ -2227,12 +2234,15 @@ nfe_jrxeof(struct nfe_softc *sc, int cou
 		NFE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		NFE_LOCK(sc);
+		rx_npkts++;
 	}
 
 	if (prog > 0)
 		bus_dmamap_sync(sc->jrxq.jrx_desc_tag, sc->jrxq.jrx_desc_map,
 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
+	if (rx_npktsp != NULL)
+		*rx_npktsp = rx_npkts;
 	return (count > 0 ? 0 : EAGAIN);
 }
 

Modified: head/sys/dev/re/if_re.c
==============================================================================
--- head/sys/dev/re/if_re.c	Sat May 30 15:07:47 2009	(r193095)
+++ head/sys/dev/re/if_re.c	Sat May 30 15:14:44 2009	(r193096)
@@ -237,11 +237,11 @@ static int re_tx_list_init	(struct rl_so
 static __inline void re_fixup_rx
 				(struct mbuf *);
 #endif
-static int re_rxeof		(struct rl_softc *);
+static int re_rxeof		(struct rl_softc *, int *);
 static void re_txeof		(struct rl_softc *);
 #ifdef DEVICE_POLLING
-static void re_poll		(struct ifnet *, enum poll_cmd, int);
-static void re_poll_locked	(struct ifnet *, enum poll_cmd, int);
+static int re_poll		(struct ifnet *, enum poll_cmd, int);
+static int re_poll_locked	(struct ifnet *, enum poll_cmd, int);
 #endif
 static int re_intr		(void *);
 static void re_tick		(void *);
@@ -1792,14 +1792,14 @@ re_rx_list_init(struct rl_softc *sc)
  * across multiple 2K mbuf cluster buffers.
  */
 static int
-re_rxeof(struct rl_softc *sc)
+re_rxeof(struct rl_softc *sc, int *rx_npktsp)
 {
 	struct mbuf		*m;
 	struct ifnet		*ifp;
 	int			i, total_len;
 	struct rl_desc		*cur_rx;
 	u_int32_t		rxstat, rxvlan;
-	int			maxpkt = 16;
+	int			maxpkt = 16, rx_npkts = 0;
 
 	RL_LOCK_ASSERT(sc);
 
@@ -1982,6 +1982,7 @@ re_rxeof(struct rl_softc *sc)
 		RL_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
 		RL_LOCK(sc);
+		rx_npkts++;
 	}
 
 	/* Flush the RX DMA ring */
@@ -1992,6 +1993,8 @@ re_rxeof(struct rl_softc *sc)
 
 	sc->rl_ldata.rl_rx_prodidx = i;
 
+	if (rx_npktsp != NULL)
+		*rx_npktsp = rx_npkts;
 	if (maxpkt)
 		return(EAGAIN);
 
@@ -2092,26 +2095,29 @@ re_tick(void *xsc)
 }
 
 #ifdef DEVICE_POLLING
-static void
+static int
 re_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct rl_softc *sc = ifp->if_softc;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905301514.n4UFEi5F011371>