From 44bbb14b5bb548a4de96e7ffebca7d70b721f6e1 Mon Sep 17 00:00:00 2001 From: bms Date: Fri, 9 Jul 2004 02:28:23 +0000 Subject: Further improve locking in xl(4): - Avoid an additional lock acquire/release when leaving xl_intr(), by changing xl_start*() to xl_start*_locked(), and calling the appropriate routine by chip revision (as the DMA descriptors are different). - Simplify the appropriate routines now that they are called with the lock held. This should save a significant amount of CPU cycles spent on servicing each interrupt for both UP and SMP whilst remaining MPSAFE. Tested by: rwatson --- sys/pci/if_xl.c | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 21 deletions(-) (limited to 'sys/pci') diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index 326466a..700c98d 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -234,7 +234,9 @@ static void xl_txeof_90xB (struct xl_softc *); static void xl_txeoc (struct xl_softc *); static void xl_intr (void *); static void xl_start (struct ifnet *); -static void xl_start_90xB (struct ifnet *); +static void xl_start_locked (struct ifnet *); +static void xl_start_90xB_locked + (struct ifnet *); static int xl_ioctl (struct ifnet *, u_long, caddr_t); static void xl_init (void *); static void xl_init_locked (struct xl_softc *); @@ -1476,15 +1478,14 @@ xl_attach(device_t dev) ifp->if_ioctl = xl_ioctl; ifp->if_capabilities = IFCAP_VLAN_MTU; if (sc->xl_type == XL_TYPE_905B) { - ifp->if_start = xl_start_90xB; ifp->if_hwassist = XL905B_CSUM_FEATURES; #ifdef XL905B_TXCSUM_BROKEN ifp->if_capabilities |= IFCAP_RXCSUM; #else ifp->if_capabilities |= IFCAP_HWCSUM; #endif - } else - ifp->if_start = xl_start; + } + ifp->if_start = xl_start; ifp->if_watchdog = xl_watchdog; ifp->if_init = xl_init; ifp->if_baudrate = 10000000; @@ -2281,10 +2282,14 @@ xl_intr(void *arg) } } - XL_UNLOCK(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); + } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - (*ifp->if_start)(ifp); + XL_UNLOCK(sc); } /* @@ -2429,17 +2434,33 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf *m_head) * copy of the pointers since the transmit list fragment pointers are * physical addresses. */ + static void xl_start(struct ifnet *ifp) { struct xl_softc *sc = ifp->if_softc; + + XL_LOCK(sc); + + if (sc->xl_type == XL_TYPE_905B) + xl_start_90xB_locked(ifp); + else + xl_start_locked(ifp); + + XL_UNLOCK(sc); +} + +static void +xl_start_locked(struct ifnet *ifp) +{ + struct xl_softc *sc = ifp->if_softc; struct mbuf *m_head = NULL; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; struct xl_chain *prev_tx; u_int32_t status; int error; - XL_LOCK(sc); + XL_LOCK_ASSERT(sc); /* * Check for an available queue slot. If there are none, @@ -2450,7 +2471,6 @@ xl_start(struct ifnet *ifp) xl_txeof(sc); if (sc->xl_cdata.xl_tx_free == NULL) { ifp->if_flags |= IFF_OACTIVE; - XL_UNLOCK(sc); return; } } @@ -2493,10 +2513,8 @@ xl_start(struct ifnet *ifp) /* * If there are no packets queued, bail. */ - if (cur_tx == NULL) { - XL_UNLOCK(sc); + if (cur_tx == NULL) return; - } /* * Place the request for the upload interrupt @@ -2557,12 +2575,10 @@ xl_start(struct ifnet *ifp) * we may as well take advantage of it. :) */ xl_rxeof(sc); - - XL_UNLOCK(sc); } static void -xl_start_90xB(struct ifnet *ifp) +xl_start_90xB_locked(struct ifnet *ifp) { struct xl_softc *sc = ifp->if_softc; struct mbuf *m_head = NULL; @@ -2570,10 +2586,10 @@ xl_start_90xB(struct ifnet *ifp) struct xl_chain *prev_tx; int error, idx; - XL_LOCK(sc); + XL_LOCK_ASSERT(sc); if (ifp->if_flags & IFF_OACTIVE) - goto out_locked; + return; idx = sc->xl_cdata.xl_tx_prod; start_tx = &sc->xl_cdata.xl_tx_chain[idx]; @@ -2618,7 +2634,7 @@ xl_start_90xB(struct ifnet *ifp) * If there are no packets queued, bail. */ if (cur_tx == NULL) - goto out_locked; + return; /* * Place the request for the upload interrupt @@ -2640,9 +2656,6 @@ xl_start_90xB(struct ifnet *ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; - -out_locked: - XL_UNLOCK(sc); } static void -- cgit v1.1