PERFORCE change 103172 for review
Paolo Pisati
piso at FreeBSD.org
Fri Aug 4 14:43:41 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103172
Change 103172 by piso at piso_newluxor on 2006/08/04 14:43:24
Modify again bfe: this time use a combination of
ithread handler (transmission path) and taskqueue (errors
and link handling).
The advantage of this approach is that we don't have
to introduce any mutex to synchronize the filter and
the thread/tasks, but on the other hand every driver
will grow its own taskqueue+tasks, and it will result
in some code duplication.
Affected files ...
.. //depot/projects/soc2006/intr_filter/dev/bfe/if_bfe.c#5 edit
.. //depot/projects/soc2006/intr_filter/dev/bfe/if_bfereg.h#3 edit
Differences ...
==== //depot/projects/soc2006/intr_filter/dev/bfe/if_bfe.c#5 (text+ko) ====
@@ -37,6 +37,7 @@
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/queue.h>
+#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -93,6 +94,8 @@
#endif
static int bfe_filter (void *);
static void bfe_handler (void *);
+static void bfe_errors (void *, int);
+static void bfe_stops (void *, int);
static void bfe_start (struct ifnet *);
static void bfe_start_locked (struct ifnet *);
static int bfe_ioctl (struct ifnet *, u_long, caddr_t);
@@ -419,6 +422,14 @@
ifp->if_capabilities |= IFCAP_VLAN_MTU;
ifp->if_capenable |= IFCAP_VLAN_MTU;
+ sc->sc_tq = taskqueue_create("bfe_taskq", M_NOWAIT,
+ taskqueue_thread_enqueue, &sc->sc_tq);
+ taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
+ "%s taskq", ifp->if_xname);
+
+ TASK_INIT(&sc->sc_errorstask, 0, bfe_errors, sc);
+ TASK_INIT(&sc->sc_stoptask, 0, bfe_stops, sc);
+
/*
* Hook interrupt last to avoid having to lock softc
*/
@@ -464,6 +475,9 @@
device_delete_child(dev, sc->bfe_miibus);
bfe_release_resources(sc);
+ taskqueue_drain(sc->sc_tq, &sc->sc_stoptask);
+ taskqueue_drain(sc->sc_tq, &sc->sc_errorstask);
+ taskqueue_free(sc->sc_tq);
BFE_UNLOCK(sc);
mtx_destroy(&sc->bfe_mtx);
@@ -1194,9 +1208,10 @@
bfe_filter(void *xsc)
{
struct bfe_softc *sc = xsc;
- u_int32_t imask;
+ struct ifnet *ifp;
+ u_int32_t imask, istat, flag;
- sc->bfe_istat = CSR_READ_4(sc, BFE_ISTAT);
+ istat = CSR_READ_4(sc, BFE_ISTAT);
imask = CSR_READ_4(sc, BFE_IMASK);
/*
@@ -1204,49 +1219,28 @@
* chips interrupt mask register to 0 doesn't actually stop the
* interrupts
*/
- sc->bfe_istat &= imask;
- CSR_WRITE_4(sc, BFE_ISTAT, sc->bfe_istat);
+ istat &= imask;
+ CSR_WRITE_4(sc, BFE_ISTAT, istat);
CSR_READ_4(sc, BFE_ISTAT);
/* not expecting this interrupt, disregard it */
- if(sc->bfe_istat == 0)
+ if(istat == 0)
return (FILTER_STRAY);
- /* disable interrupts - not that it actually does..*/
- CSR_WRITE_4(sc, BFE_IMASK, 0);
- CSR_READ_4(sc, BFE_IMASK);
-
- return (FILTER_HANDLED | FILTER_SCHEDULE_THREAD);
-}
-
-static void
-bfe_handler(void *xsc)
-{
- struct bfe_softc *sc = xsc;
- struct ifnet *ifp;
- u_int32_t istat, flag;
-
- ifp = sc->bfe_ifp;
-
- BFE_LOCK(sc);
-
- istat = sc->bfe_istat;
if(istat & BFE_ISTAT_ERRORS) {
-
if (istat & BFE_ISTAT_DSCE) {
printf("if_bfe Descriptor Error\n");
- bfe_stop(sc);
- BFE_UNLOCK(sc);
- return;
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_stoptask);
+ return (FILTER_HANDLED);
}
if (istat & BFE_ISTAT_DPE) {
printf("if_bfe Descriptor Protocol Error\n");
- bfe_stop(sc);
- BFE_UNLOCK(sc);
- return;
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_stoptask);
+ return (FILTER_HANDLED);
}
+ ifp = sc->bfe_ifp;
flag = CSR_READ_4(sc, BFE_DMATX_STAT);
if(flag & BFE_STAT_EMASK)
ifp->if_oerrors++;
@@ -1254,28 +1248,61 @@
flag = CSR_READ_4(sc, BFE_DMARX_STAT);
if(flag & BFE_RX_FLAG_ERRORS)
ifp->if_ierrors++;
+
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_errorstask);
+ return (FILTER_HANDLED);
+ }
+
+ /* disable interrupts - not that it actually does..*/
+ CSR_WRITE_4(sc, BFE_IMASK, 0);
+ CSR_READ_4(sc, BFE_IMASK);
+
+ return (FILTER_HANDLED | FILTER_SCHEDULE_THREAD);
+}
+
+static void
+bfe_stops(void *context, int p __unused) {
+ struct bfe_softc *sc = context;
+
+ BFE_LOCK(sc);
+ bfe_stop(sc);
+ BFE_UNLOCK(sc);
+}
+
+static void
+bfe_errors(void *context, int p __unused) {
+ struct bfe_softc *sc = context;
+ struct ifnet *ifp;
+
+ BFE_LOCK(sc);
+ ifp = sc->bfe_ifp;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ bfe_init_locked(sc);
+ BFE_UNLOCK(sc);
+}
+
+static void
+bfe_handler(void *xsc) {
+ struct bfe_softc *sc = xsc;
+ struct ifnet *ifp;
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- bfe_init_locked(sc);
- }
+ BFE_LOCK(sc);
+ ifp = sc->bfe_ifp;
- /* A packet was received */
- if(istat & BFE_ISTAT_RX)
- bfe_rxeof(sc);
+ /* A packet was received */
+ bfe_rxeof(sc);
/* A packet was sent */
- if(istat & BFE_ISTAT_TX)
- bfe_txeof(sc);
+ bfe_txeof(sc);
/* We have packets pending, fire them out */
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
bfe_start_locked(ifp);
- BFE_UNLOCK(sc);
-
/* Enable interrupts */
CSR_WRITE_4(sc, BFE_IMASK, BFE_IMASK_DEF);
+ BFE_UNLOCK(sc);
}
#if 0
==== //depot/projects/soc2006/intr_filter/dev/bfe/if_bfereg.h#3 (text+ko) ====
@@ -510,7 +510,9 @@
struct bfe_data bfe_tx_ring[BFE_TX_LIST_CNT]; /* XXX */
struct bfe_data bfe_rx_ring[BFE_RX_LIST_CNT]; /* XXX */
struct mtx bfe_mtx;
- u_int32_t bfe_istat;
+ struct taskqueue *sc_tq; /* private task queue */
+ struct task sc_stoptask;
+ struct task sc_errorstask;
u_int32_t bfe_flags;
u_int32_t bfe_imask;
u_int32_t bfe_dma_offset;
More information about the p4-projects
mailing list