PERFORCE change 103263 for review

Paolo Pisati piso at FreeBSD.org
Sat Aug 5 18:06:21 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=103263

Change 103263 by piso at piso_newluxor on 2006/08/05 18:06:14

	Convert xl to use a filter+ithread handler.
	Unfortunately, under heavy load (trying to transfer 
	a big file from 2 boxes in a LAN) i get many 
	'watchdog timeout' errors: i'll try to fix it later.  

Affected files ...

.. //depot/projects/soc2006/intr_filter/pci/if_xl.c#3 edit
.. //depot/projects/soc2006/intr_filter/pci/if_xlreg.h#2 edit

Differences ...

==== //depot/projects/soc2006/intr_filter/pci/if_xl.c#3 (text+ko) ====

@@ -233,11 +233,15 @@
 static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf *);
 static void xl_rxeof(struct xl_softc *);
 static void xl_rxeof_task(void *, int);
-static int xl_rx_resync(struct xl_softc *);
+__unused static int xl_rx_resync(struct xl_softc *);
 static void xl_txeof(struct xl_softc *);
 static void xl_txeof_90xB(struct xl_softc *);
 static void xl_txeoc(struct xl_softc *);
 static void xl_intr(void *);
+static int xl_filter(void *);
+static void xl_stat_tx_complete(void *, int);
+static void xl_stat_adfail(void *, int);
+static void xl_stat_statsoflow(void *, int);
 static void xl_start(struct ifnet *);
 static void xl_start_locked(struct ifnet *);
 static void xl_start_90xB_locked(struct ifnet *);
@@ -1600,13 +1604,21 @@
 		CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
 	}
 
+	sc->xl_tq = taskqueue_create("xl_taskq", M_NOWAIT,
+				     taskqueue_thread_enqueue, &sc->xl_tq);
+	taskqueue_start_threads(&sc->xl_tq, 1, 
+				PI_NET, "%s taskq", ifp->if_xname);	
+	TASK_INIT(&sc->xl_stat_tx_complete, 0, xl_stat_tx_complete, sc);
+	TASK_INIT(&sc->xl_stat_adfail, 0, xl_stat_adfail, sc);
+	TASK_INIT(&sc->xl_stat_statsoflow, 0, xl_stat_statsoflow, sc);
+
 	/*
 	 * Call MI attach routine.
 	 */
 	ether_ifattach(ifp, eaddr);
 
 	error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET | INTR_MPSAFE,
-	    NULL, xl_intr, sc, &sc->xl_intrhand);
+	    xl_filter, xl_intr, sc, &sc->xl_intrhand);
 	if (error) {
 		device_printf(dev, "couldn't set up irq\n");
 		ether_ifdetach(ifp);
@@ -1715,6 +1727,7 @@
 		callout_drain(&sc->xl_stat_callout);
 		ether_ifdetach(ifp);
 	}
+	taskqueue_free(sc->xl_tq);
 	if (sc->xl_miibus)
 		device_delete_child(dev, sc->xl_miibus);
 	bus_generic_detach(dev);
@@ -1751,7 +1764,6 @@
 		    sc->xl_ldata.xl_tx_dmamap);
 		bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
 	}
-
 	mtx_destroy(&sc->xl_mtx);
 
 	return (0);
@@ -1925,7 +1937,7 @@
 	return (0);
 }
 
-static int
+__unused static int
 xl_rx_resync(struct xl_softc *sc)
 {
 	struct xl_chain_onefrag	*pos;
@@ -2274,68 +2286,94 @@
 }
 
 static void
-xl_intr(void *arg)
+xl_stat_tx_complete(void *_sc, int p __unused) {
+	struct xl_softc		*sc = _sc;
+	struct ifnet		*ifp = sc->xl_ifp;
+
+	XL_LOCK(sc);
+	ifp->if_oerrors++;
+	xl_txeoc(sc);
+	XL_UNLOCK(sc);
+}
+
+static void
+xl_stat_adfail(void *_sc, int p __unused) {
+	struct xl_softc		*sc = _sc;
+
+	XL_LOCK(sc);
+	xl_reset(sc);
+	xl_init_locked(sc);
+	XL_UNLOCK(sc);
+}
+
+static void
+xl_stat_statsoflow(void *_sc, int p __unused) {
+	struct xl_softc		*sc = _sc;
+
+	XL_LOCK(sc);
+	sc->xl_stats_no_timeout = 1;
+	xl_stats_update_locked(sc);
+	sc->xl_stats_no_timeout = 0;	
+	XL_UNLOCK(sc);
+}
+
+static int
+xl_filter(void *arg)
 {
 	struct xl_softc		*sc = arg;
-	struct ifnet		*ifp = sc->xl_ifp;
 	u_int16_t		status;
+	int                     ret = FILTER_HANDLED;
+
+	status = CSR_READ_2(sc, XL_STATUS); 
+	status &= XL_INTRS;
 
-	XL_LOCK(sc);
+	if (status == 0xFFFF)
+		return (FILTER_STRAY);
 
-#ifdef DEVICE_POLLING
-	if (ifp->if_capenable & IFCAP_POLLING) {
-		XL_UNLOCK(sc);
-		return;
-	}
-#endif
+	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|(status & XL_INTRS));
+		    
+	if (status & XL_STAT_UP_COMPLETE)
+		ret |= FILTER_SCHEDULE_THREAD;
 
-	while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
-	    status != 0xFFFF) {
-		CSR_WRITE_2(sc, XL_COMMAND,
-		    XL_CMD_INTR_ACK|(status & XL_INTRS));
+	if (status & XL_STAT_DOWN_COMPLETE)
+		ret |= FILTER_SCHEDULE_THREAD;
 
-		if (status & XL_STAT_UP_COMPLETE) {
-			int	curpkts;
+	if (status & XL_STAT_TX_COMPLETE)
+		taskqueue_enqueue(sc->xl_tq, &sc->xl_stat_tx_complete);
 
-			curpkts = ifp->if_ipackets;
-			xl_rxeof(sc);
-			if (curpkts == ifp->if_ipackets) {
-				while (xl_rx_resync(sc))
-					xl_rxeof(sc);
-			}
-		}
+	if (status & XL_STAT_ADFAIL)
+		taskqueue_enqueue(sc->xl_tq, &sc->xl_stat_adfail);
 
-		if (status & XL_STAT_DOWN_COMPLETE) {
-			if (sc->xl_type == XL_TYPE_905B)
-				xl_txeof_90xB(sc);
-			else
-				xl_txeof(sc);
-		}
+	if (status & XL_STAT_STATSOFLOW)
+		taskqueue_enqueue(sc->xl_tq, &sc->xl_stat_statsoflow);
 
-		if (status & XL_STAT_TX_COMPLETE) {
-			ifp->if_oerrors++;
-			xl_txeoc(sc);
-		}
+	/* Disable interrupts */
+	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
 
-		if (status & XL_STAT_ADFAIL) {
-			xl_reset(sc);
-			xl_init_locked(sc);
-		}
+	return (ret);
+}
 
-		if (status & XL_STAT_STATSOFLOW) {
-			sc->xl_stats_no_timeout = 1;
-			xl_stats_update_locked(sc);
-			sc->xl_stats_no_timeout = 0;
-		}
-	}
+static void
+xl_intr(void *arg) {
+	struct xl_softc		*sc = arg;
+	struct ifnet		*ifp = sc->xl_ifp;
 
+	XL_LOCK(sc);	
+	xl_rxeof(sc);
+	if (sc->xl_type == XL_TYPE_905B)
+		xl_txeof_90xB(sc);
+	else
+		xl_txeof(sc);	
+	
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
 		if (sc->xl_type == XL_TYPE_905B)
 			xl_start_90xB_locked(ifp);
 		else
 			xl_start_locked(ifp);
 	}
-
+	/* Enable interrupts */
+	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
+	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
 	XL_UNLOCK(sc);
 }
 

==== //depot/projects/soc2006/intr_filter/pci/if_xlreg.h#2 (text+ko) ====

@@ -608,6 +608,10 @@
 	bus_space_tag_t		xl_ftag;
 	struct mtx		xl_mtx;
 	struct task		xl_task;
+	struct taskqueue        *xl_tq;
+	struct task             xl_stat_tx_complete;
+	struct task             xl_stat_adfail;
+	struct task             xl_stat_statsoflow;
 #ifdef DEVICE_POLLING
 	int			rxcycles;
 #endif


More information about the p4-projects mailing list