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