summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2004-07-09 02:28:23 +0000
committerbms <bms@FreeBSD.org>2004-07-09 02:28:23 +0000
commit44bbb14b5bb548a4de96e7ffebca7d70b721f6e1 (patch)
tree721449cee0ff0e491c1a793b188dfd9f8e87d030 /sys/pci
parente828b3b382267da4287d50e72c6a79c3ce764ed4 (diff)
downloadFreeBSD-src-44bbb14b5bb548a4de96e7ffebca7d70b721f6e1.zip
FreeBSD-src-44bbb14b5bb548a4de96e7ffebca7d70b721f6e1.tar.gz
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
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_xl.c55
1 files changed, 34 insertions, 21 deletions
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
OpenPOWER on IntegriCloud