Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Oct 2003 13:58:29 -0700 (PDT)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 39273 for review
Message-ID:  <200310062058.h96KwTi0066764@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39273

Change 39273 by sam@sam_ebb on 2003/10/06 13:58:23

	add simple locking

Affected files ...

.. //depot/projects/netperf/sys/dev/bge/if_bge.c#10 edit
.. //depot/projects/netperf/sys/dev/bge/if_bgereg.h#5 edit

Differences ...

==== //depot/projects/netperf/sys/dev/bge/if_bge.c#10 (text+ko) ====

@@ -184,6 +184,7 @@
 static void bge_txeof		(struct bge_softc *);
 static void bge_rxeof		(struct bge_softc *);
 
+static void bge_tick_locked	(struct bge_softc *);
 static void bge_tick		(void *);
 static void bge_stats_update	(struct bge_softc *);
 static void bge_stats_update_regs
@@ -192,8 +193,10 @@
 					u_int32_t *);
 
 static void bge_intr		(void *);
+static void bge_start_locked	(struct ifnet *);
 static void bge_start		(struct ifnet *);
 static int bge_ioctl		(struct ifnet *, u_long, caddr_t);
+static void bge_init_locked	(struct bge_softc *);
 static void bge_init		(void *);
 static void bge_stop		(struct bge_softc *);
 static void bge_watchdog		(struct ifnet *);
@@ -1154,6 +1157,8 @@
 	u_int32_t hashes[4] = { 0, 0, 0, 0 };
 	int h, i;
 
+	BGE_LOCK_ASSERT(sc);
+
 	ifp = &sc->arpcom.ac_if;
 
 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
@@ -2225,15 +2230,12 @@
 bge_attach(dev)
 	device_t dev;
 {
-	int s;
 	struct ifnet *ifp;
 	struct bge_softc *sc;
 	u_int32_t hwcfg = 0;
 	u_int32_t mac_addr = 0;
 	int unit, error = 0, rid;
 
-	s = splimp();
-
 	sc = device_get_softc(dev);
 	unit = device_get_unit(dev);
 	sc->bge_dev = dev;
@@ -2270,16 +2272,9 @@
 		goto fail;
 	}
 
-	error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET,
-	   bge_intr, sc, &sc->bge_intrhand);
+	sc->bge_unit = unit;
 
-	if (error) {
-		bge_release_resources(sc);
-		printf("bge%d: couldn't set up irq\n", unit);
-		goto fail;
-	}
-
-	sc->bge_unit = unit;
+	BGE_LOCK_INIT(sc, device_get_nameunit(dev));
 
 	/* Try to reset the chip. */
 	bge_reset(sc);
@@ -2449,11 +2444,20 @@
 	 * Call MI attach routine.
 	 */
 	ether_ifattach(ifp, sc->arpcom.ac_enaddr);
-	callout_handle_init(&sc->bge_stat_ch);
+	callout_init(&sc->bge_stat_ch, CALLOUT_MPSAFE);
+
+	/*
+	 * Hookup IRQ last.
+	 */
+	error = bus_setup_intr(dev, sc->bge_irq, INTR_TYPE_NET | INTR_MPSAFE,
+	   bge_intr, sc, &sc->bge_intrhand);
+
+	if (error) {
+		bge_release_resources(sc);
+		printf("bge%d: couldn't set up irq\n", unit);
+	}
 
 fail:
-	splx(s);
-
 	return(error);
 }
 
@@ -2463,16 +2467,16 @@
 {
 	struct bge_softc *sc;
 	struct ifnet *ifp;
-	int s;
-
-	s = splimp();
 
 	sc = device_get_softc(dev);
 	ifp = &sc->arpcom.ac_if;
 
-	ether_ifdetach(ifp);
+	BGE_LOCK(sc);
 	bge_stop(sc);
 	bge_reset(sc);
+	BGE_UNLOCK(sc);
+
+	ether_ifdetach(ifp);
 
 	if (sc->bge_tbi) {
 		ifmedia_removeall(&sc->bge_ifmedia);
@@ -2485,8 +2489,6 @@
 	if (sc->bge_asicrev != BGE_ASICREV_BCM5705)
 		bge_free_jumbo_mem(sc);
 
-	splx(s);
-
 	return(0);
 }
 
@@ -2516,6 +2518,9 @@
 
 	bge_dma_free(sc);
 
+	if (mtx_initialized(&sc->bge_mtx))	/* XXX */
+		BGE_LOCK_DESTROY(sc);
+
         return;
 }
 
@@ -2620,6 +2625,8 @@
 	struct ifnet *ifp;
 	int stdcnt = 0, jumbocnt = 0;
 
+	BGE_LOCK_ASSERT(sc);
+
 	ifp = &sc->arpcom.ac_if;
 
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
@@ -2732,7 +2739,9 @@
 		if (have_tag)
 			VLAN_INPUT_TAG(ifp, m, vlan_tag, continue);
 
+		BGE_UNLOCK(sc);
 		(*ifp->if_input)(ifp, m);
+		BGE_LOCK(sc);
 	}
 
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_return_ring_tag,
@@ -2762,6 +2771,8 @@
 	struct bge_tx_bd *cur_tx = NULL;
 	struct ifnet *ifp;
 
+	BGE_LOCK_ASSERT(sc);
+
 	ifp = &sc->arpcom.ac_if;
 
 	/*
@@ -2805,6 +2816,8 @@
 	sc = xsc;
 	ifp = &sc->arpcom.ac_if;
 
+	BGE_LOCK(sc);
+
 	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
 	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTWRITE);
 
@@ -2837,8 +2850,8 @@
 		status = CSR_READ_4(sc, BGE_MAC_STS);
 		if (status & BGE_MACSTAT_MI_INTERRUPT) {
 			sc->bge_link = 0;
-			untimeout(bge_tick, sc, sc->bge_stat_ch);
-			bge_tick(sc);
+			callout_stop(&sc->bge_stat_ch);
+			bge_tick_locked(sc);
 			/* Clear the interrupt */
 			CSR_WRITE_4(sc, BGE_MAC_EVT_ENB,
 			    BGE_EVTENB_MI_INTERRUPT);
@@ -2864,8 +2877,8 @@
 			if (!(status & (BGE_MACSTAT_PORT_DECODE_ERROR|
 			    BGE_MACSTAT_MI_COMPLETE))) {
 				sc->bge_link = 0;
-				untimeout(bge_tick, sc, sc->bge_stat_ch);
-				bge_tick(sc);
+				callout_stop(&sc->bge_stat_ch);
+				bge_tick_locked(sc);
 			}
 			/* Clear the interrupt */
 			CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
@@ -2894,35 +2907,32 @@
 	CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
 
 	if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL)
-		bge_start(ifp);
+		bge_start_locked(ifp);
+
+	BGE_UNLOCK(sc);
 
 	return;
 }
 
 static void
-bge_tick(xsc)
-	void *xsc;
+bge_tick_locked(sc)
+	struct bge_softc *sc;
 {
-	struct bge_softc *sc;
 	struct mii_data *mii = NULL;
 	struct ifmedia *ifm = NULL;
 	struct ifnet *ifp;
-	int s;
 
-	sc = xsc;
 	ifp = &sc->arpcom.ac_if;
 
-	s = splimp();
+	BGE_LOCK_ASSERT(sc);
 
 	if (sc->bge_asicrev == BGE_ASICREV_BCM5705)
 		bge_stats_update_regs(sc);
 	else
 		bge_stats_update(sc);
-	sc->bge_stat_ch = timeout(bge_tick, sc, hz);
-	if (sc->bge_link) {
-		splx(s);
+	callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
+	if (sc->bge_link)
 		return;
-	}
 
 	if (sc->bge_tbi) {
 		ifm = &sc->bge_ifmedia;
@@ -2932,9 +2942,8 @@
 			CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
 			printf("bge%d: gigabit link up\n", sc->bge_unit);
 			if (ifp->if_snd.ifq_head != NULL)
-				bge_start(ifp);
+				bge_start_locked(ifp);
 		}
-		splx(s);
 		return;
 	}
 
@@ -2949,12 +2958,23 @@
 			printf("bge%d: gigabit link up\n",
 			   sc->bge_unit);
 		if (ifp->if_snd.ifq_head != NULL)
-			bge_start(ifp);
+			bge_start_locked(ifp);
 	}
 
-	splx(s);
+	return;
+}
+
+static void
+bge_tick(xsc)
+	void *xsc;
+{
+	struct bge_softc *sc;
+
+	sc = xsc;
 
-	return;
+	BGE_LOCK(sc);
+	bge_tick_locked(sc);
+	BGE_UNLOCK(sc);
 }
 
 static void
@@ -3093,7 +3113,7 @@
  * to the mbuf data regions directly in the transmit descriptors.
  */
 static void
-bge_start(ifp)
+bge_start_locked(ifp)
 	struct ifnet *ifp;
 {
 	struct bge_softc *sc;
@@ -3162,23 +3182,35 @@
 	return;
 }
 
+/*
+ * Main transmit routine. To avoid having to do mbuf copies, we put pointers
+ * to the mbuf data regions directly in the transmit descriptors.
+ */
 static void
-bge_init(xsc)
-	void *xsc;
+bge_start(ifp)
+	struct ifnet *ifp;
+{
+	struct bge_softc *sc;
+
+	sc = ifp->if_softc;
+	BGE_LOCK(sc);
+	bge_start_locked(ifp);
+	BGE_UNLOCK(sc);
+}
+
+static void
+bge_init_locked(sc)
+	struct bge_softc *sc;
 {
-	struct bge_softc *sc = xsc;
 	struct ifnet *ifp;
 	u_int16_t *m;
-        int s;
 
-	s = splimp();
+	BGE_LOCK_ASSERT(sc);
 
 	ifp = &sc->arpcom.ac_if;
 
-	if (ifp->if_flags & IFF_RUNNING) {
-		splx(s);
+	if (ifp->if_flags & IFF_RUNNING)
 		return;
-	}
 
 	/* Cancel pending I/O and flush buffers. */
 	bge_stop(sc);
@@ -3191,7 +3223,6 @@
 	 */
 	if (bge_blockinit(sc)) {
 		printf("bge%d: initialization failure\n", sc->bge_unit);
-		splx(s);
 		return;
 	}
 
@@ -3266,9 +3297,20 @@
 	ifp->if_flags |= IFF_RUNNING;
 	ifp->if_flags &= ~IFF_OACTIVE;
 
-	splx(s);
+	callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
+
+	return;
+}
+
+static void
+bge_init(xsc)
+	void *xsc;
+{
+	struct bge_softc *sc = xsc;
 
-	sc->bge_stat_ch = timeout(bge_tick, sc, hz);
+	BGE_LOCK(sc);
+	bge_init_locked(sc);
+	BGE_UNLOCK(sc);
 
 	return;
 }
@@ -3365,11 +3407,9 @@
 {
 	struct bge_softc *sc = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *) data;
-	int s, mask, error = 0;
+	int mask, error = 0;
 	struct mii_data *mii;
 
-	s = splimp();
-
 	switch(command) {
 	case SIOCSIFMTU:
 		/* Disallow jumbo frames on 5705. */
@@ -3383,6 +3423,7 @@
 		}
 		break;
 	case SIOCSIFFLAGS:
+		BGE_LOCK(sc);
 		if (ifp->if_flags & IFF_UP) {
 			/*
 			 * If only the state of the PROMISC flag changed,
@@ -3403,19 +3444,22 @@
 				BGE_CLRBIT(sc, BGE_RX_MODE,
 				    BGE_RXMODE_RX_PROMISC);
 			} else
-				bge_init(sc);
+				bge_init_locked(sc);
 		} else {
 			if (ifp->if_flags & IFF_RUNNING) {
 				bge_stop(sc);
 			}
 		}
 		sc->bge_if_flags = ifp->if_flags;
+		BGE_UNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		if (ifp->if_flags & IFF_RUNNING) {
+			BGE_LOCK(sc);
 			bge_setmulti(sc);
+			BGE_UNLOCK(sc);
 			error = 0;
 		}
 		break;
@@ -3445,8 +3489,6 @@
 		break;
 	}
 
-	(void)splx(s);
-
 	return(error);
 }
 
@@ -3481,12 +3523,14 @@
 	struct mii_data *mii = NULL;
 	int mtmp, itmp;
 
+	BGE_LOCK_ASSERT(sc);
+
 	ifp = &sc->arpcom.ac_if;
 
 	if (!sc->bge_tbi)
 		mii = device_get_softc(sc->bge_miibus);
 
-	untimeout(bge_tick, sc, sc->bge_stat_ch);
+	callout_stop(&sc->bge_stat_ch);
 
 	/*
 	 * Disable all of the receiver blocks
@@ -3583,8 +3627,10 @@
 
 	sc = device_get_softc(dev);
 
+	BGE_LOCK(sc);
 	bge_stop(sc); 
 	bge_reset(sc);
+	BGE_UNLOCK(sc);
 
 	return;
 }

==== //depot/projects/netperf/sys/dev/bge/if_bgereg.h#5 (text+ko) ====

@@ -2258,6 +2258,7 @@
 struct bge_softc {
 	struct arpcom		arpcom;		/* interface info */
 	device_t		bge_dev;
+	struct mtx		bge_mtx;
 	device_t		bge_miibus;
 	bus_space_handle_t	bge_bhandle;
 	vm_offset_t		bge_vhandle;
@@ -2293,7 +2294,14 @@
 	int			bge_if_flags;
 	int			bge_txcnt;
 	int			bge_link;
-	struct callout_handle	bge_stat_ch;
+	struct callout		bge_stat_ch;
 	char			*bge_vpd_prodname;
 	char			*bge_vpd_readonly;
 };
+
+#define	BGE_LOCK_INIT(_sc, _name) \
+	mtx_init(&(_sc)->bge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
+#define	BGE_LOCK(_sc)		mtx_lock(&(_sc)->bge_mtx)
+#define	BGE_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->bge_mtx, MA_OWNED)
+#define	BGE_UNLOCK(_sc)		mtx_unlock(&(_sc)->bge_mtx)
+#define	BGE_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->bge_mtx)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310062058.h96KwTi0066764>