Change 58244 by rwatson@rwatson_tislabs on 2004/07/26 17:10:28

	Integrate rwatson_netperf@58163 into rwatson_netperf_merge:
	changes for IFF_NEEDSGIANT.

Affected files ...

... //depot/user/rwatson/netperf_merge/sys/dev/firewire/if_fwe.c#4 integrate
... //depot/user/rwatson/netperf_merge/sys/dev/usb/if_aue.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/dev/usb/if_axe.c#6 integrate
... //depot/user/rwatson/netperf_merge/sys/dev/usb/if_cue.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/dev/usb/if_kue.c#4 integrate
... //depot/user/rwatson/netperf_merge/sys/dev/usb/if_rue.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/dev/usb/if_udav.c#6 integrate
... //depot/user/rwatson/netperf_merge/sys/net/if.c#8 integrate
... //depot/user/rwatson/netperf_merge/sys/net/if.h#4 integrate
... //depot/user/rwatson/netperf_merge/sys/net/if_ethersubr.c#6 integrate
... //depot/user/rwatson/netperf_merge/sys/net/if_var.h#10 integrate
... //depot/user/rwatson/netperf_merge/sys/net80211/ieee80211_output.c#3 integrate
... //depot/user/rwatson/netperf_merge/sys/net80211/ieee80211_proto.c#3 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_dc.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_de.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_pcn.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_sf.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_sk.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_ste.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_ti.c#5 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_tl.c#3 integrate
... //depot/user/rwatson/netperf_merge/sys/pci/if_wb.c#5 integrate

Differences ...

==== //depot/user/rwatson/netperf_merge/sys/dev/firewire/if_fwe.c#4 (text+ko) ====

@@ -215,7 +215,8 @@
 	ifp->if_start = fwe_start;
 	ifp->if_ioctl = fwe_ioctl;
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
+	ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|
+	    IFF_NEEDSGIANT);
 	ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE;
 
 	s = splimp();
@@ -487,6 +488,8 @@
 	struct fwe_softc *fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe;
 	int s;
 
+	GIANT_REQUIRED;
+
 	FWEDEBUG(ifp, "starting\n");
 
 	if (fwe->dma_ch < 0) {

==== //depot/user/rwatson/netperf_merge/sys/dev/usb/if_aue.c#5 (text+ko) ====

@@ -717,7 +717,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, "aue", sc->aue_unit);
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = aue_ioctl;
 	ifp->if_start = aue_start;
 	ifp->if_watchdog = aue_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/dev/usb/if_axe.c#6 (text+ko) ====

@@ -476,7 +476,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, "axe", sc->axe_unit);
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = axe_ioctl;
 	ifp->if_start = axe_start;
 	ifp->if_watchdog = axe_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/dev/usb/if_cue.c#5 (text+ko) ====

@@ -507,7 +507,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, "cue", sc->cue_unit);
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = cue_ioctl;
 	ifp->if_start = cue_start;
 	ifp->if_watchdog = cue_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/dev/usb/if_kue.c#4 (text+ko) ====

@@ -481,7 +481,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, "kue", sc->kue_unit);
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = kue_ioctl;
 	ifp->if_start = kue_start;
 	ifp->if_watchdog = kue_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/dev/usb/if_rue.c#5 (text+ko) ====

@@ -660,7 +660,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, "rue", sc->rue_unit);
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST ||
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = rue_ioctl;
 	ifp->if_start = rue_start;
 	ifp->if_watchdog = rue_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/dev/usb/if_udav.c#6 (text+ko) ====

@@ -400,7 +400,8 @@
 #elif defined(__FreeBSD__)
 	if_initname(ifp, "udav",  device_get_unit(self));
 #endif
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_start = udav_start;
 	ifp->if_ioctl = udav_ioctl;
 	ifp->if_watchdog = udav_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/net/if.c#8 (text+ko) ====

@@ -50,6 +50,7 @@
 #include <sys/sockio.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 #include <sys/domain.h>
 #include <sys/jail.h>
 #include <machine/stdarg.h>
@@ -92,6 +93,7 @@
 static void	link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
 static int	if_rtdel(struct radix_node *, void *);
 static int	ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
+static void	if_start_deferred(void *context, int pending);
 #ifdef INET6
 /*
  * XXX: declare here to avoid to include many inet6 related files..
@@ -365,6 +367,7 @@
 	struct sockaddr_dl *sdl;
 	struct ifaddr *ifa;
 
+	TASK_INIT(&ifp->if_starttask, 0, if_start_deferred, ifp);
 	IF_AFDATA_LOCK_INIT(ifp);
 	ifp->if_afdata_initialized = 0;
 	IFNET_WLOCK();
@@ -983,6 +986,10 @@
  * Handle interface watchdog timer routines.  Called
  * from softclock, we decrement timers (if set) and
  * call the appropriate interface routine on expiration.
+ *
+ * XXXRW: Note that because timeouts run with Giant, if_watchdog() is called
+ * holding Giant.  If we switch to an MPSAFE callout, we likely need to grab
+ * Giant before entering if_watchdog() on an IFF_NEEDSGIANT interface.
  */
 static void
 if_slowtimo(void *arg)
@@ -1839,5 +1846,47 @@
 	return (retval);
 }
 
+/*
+ * When an interface is marked IFF_NEEDSGIANT, its if_start() routine cannot
+ * be called without Giant.  However, we often can't acquire the Giant lock
+ * at those points; instead, we run it via a task queue that holds Giant via
+ * if_start_deferred.
+ *
+ * XXXRW: We need to make sure that the ifnet isn't fully detached until any
+ * outstanding if_start_deferred() tasks that will run after the free.  This
+ * probably means waiting in if_detach().
+ */
+void
+if_start(struct ifnet *ifp)
+{
+
+	NET_ASSERT_GIANT();
+                
+        if ((ifp->if_flags & IFF_NEEDSGIANT) != 0 && debug_mpsafenet != 0) {
+                if (mtx_owned(&Giant))
+                        (*(ifp)->if_start)(ifp);
+                else
+			taskqueue_enqueue(taskqueue_swi_giant,
+			    &ifp->if_starttask);
+        } else
+                (*(ifp)->if_start)(ifp);
+}
+
+static void
+if_start_deferred(void *context, int pending)
+{
+	struct ifnet *ifp;
+
+	/*
+	 * This code must be entered with Giant, and should never run if
+	 * we're not running with debug.mpsafenet.
+	 */
+	KASSERT(debug_mpsafenet != 0, ("if_start_deferred: debug.mpsafenet"));
+	GIANT_REQUIRED;
+
+	ifp = (struct ifnet *)context;
+	(ifp->if_start)(ifp);
+}
+
 SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
 SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");

==== //depot/user/rwatson/netperf_merge/sys/net/if.h#4 (text+ko) ====

@@ -126,6 +126,7 @@
 #define	IFF_PPROMISC	0x20000		/* user-requested promisc mode */
 #define	IFF_MONITOR	0x40000		/* user-requested monitor mode */
 #define	IFF_STATICARP	0x80000		/* static ARP */
+#define	IFF_NEEDSGIANT	0x100000	/* hold Giant over if_start calls */
 
 /* flags set internally only: */
 #define	IFF_CANTCHANGE \

==== //depot/user/rwatson/netperf_merge/sys/net/if_ethersubr.c#6 (text+ko) ====

@@ -888,6 +888,8 @@
 			break; 
 	if (i != ifp->if_addrlen)
 		if_printf(ifp, "Ethernet address: %6D\n", llc, ":");
+	if (debug_mpsafenet && (ifp->if_flags & IFF_NEEDSGIANT) != 0)
+		if_printf(ifp, "if_start running deferred for Giant\n");
 }
 
 /*

==== //depot/user/rwatson/netperf_merge/sys/net/if_var.h#10 (text+ko) ====

@@ -79,6 +79,7 @@
 #include <sys/lock.h>		/* XXX */
 #include <sys/mutex.h>		/* XXX */
 #include <sys/event.h>		/* XXX */
+#include <sys/_task.h>
 
 #define	IF_DUNIT_NONE	-1
 
@@ -191,6 +192,7 @@
 	void	*if_afdata[AF_MAX];
 	int	if_afdata_initialized;
 	struct	mtx if_afdata_mtx;
+	struct	task if_starttask;	/* task for IFF_NEEDSGIANT */
 };
 
 typedef void if_init_f_t(void *);
@@ -329,6 +331,8 @@
 #define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
 	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
 
+void	if_start(struct ifnet *);
+
 static __inline int
 if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
 {
@@ -350,7 +354,7 @@
 	_IF_ENQUEUE(ifq, m);
 	IF_UNLOCK(ifq);
 	if (ifp != NULL && !active)
-		(*ifp->if_start)(ifp);
+		if_start(ifp);
 	return (1);
 }
 #if 1 /* ALTQ */
@@ -474,7 +478,7 @@
 		if (mflags & M_MCAST)					\
 			(ifp)->if_omcasts++;				\
 		if (((ifp)->if_flags & IFF_OACTIVE) == 0)		\
-			(*(ifp)->if_start)(ifp);			\
+			if_start(ifp);					\
 	}								\
 } while (0)
 

==== //depot/user/rwatson/netperf_merge/sys/net80211/ieee80211_output.c#3 (text+ko) ====

@@ -130,7 +130,7 @@
 
 	IF_ENQUEUE(&ic->ic_mgtq, m);
 	ifp->if_timer = 1;
-	(*ifp->if_start)(ifp);
+	if_start(ifp);
 	return 0;
 }
 

==== //depot/user/rwatson/netperf_merge/sys/net80211/ieee80211_proto.c#3 (text+ko) ====

@@ -513,7 +513,7 @@
 					IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
 			}
 			ic->ic_mgt_timer = 0;
-			(*ifp->if_start)(ifp);
+			if_start(ifp);
 			break;
 		}
 		break;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_dc.c#5 (text+ko) ====


==== //depot/user/rwatson/netperf_merge/sys/pci/if_de.c#5 (text+ko) ====

@@ -4758,7 +4758,7 @@
     /* XXX: driver name/unit should be set some other way */
     ifp->if_dname = "de";
     ifp->if_dunit = sc->tulip_unit;
-    ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
+    ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_NEEDSGIANT;
     ifp->if_ioctl = tulip_ifioctl;
     ifp->if_start = tulip_ifstart;
     ifp->if_watchdog = tulip_ifwatchdog;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_pcn.c#5 (text+ko) ====

@@ -552,7 +552,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = pcn_ioctl;
 	ifp->if_start = pcn_start;
 	ifp->if_watchdog = pcn_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_sf.c#5 (text+ko) ====

@@ -706,7 +706,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = sf_ioctl;
 	ifp->if_start = sf_start;
 	ifp->if_watchdog = sf_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_sk.c#5 (text+ko) ====

@@ -1436,7 +1436,8 @@
 	ifp->if_softc = sc_if;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = sk_ioctl;
 	ifp->if_start = sk_start;
 	ifp->if_watchdog = sk_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_ste.c#5 (text+ko) ====

@@ -1074,7 +1074,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = ste_ioctl;
 	ifp->if_start = ste_start;
 	ifp->if_watchdog = ste_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_ti.c#5 (text+ko) ====

@@ -2157,7 +2157,8 @@
 	ifp = &sc->arpcom.ac_if;
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	tis[unit] = sc;
 	ifp->if_ioctl = ti_ioctl;
 	ifp->if_start = ti_start;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_tl.c#3 (text+ko) ====

@@ -1262,7 +1262,8 @@
 	ifp = &sc->arpcom.ac_if;
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = tl_ioctl;
 	ifp->if_start = tl_start;
 	ifp->if_watchdog = tl_watchdog;

==== //depot/user/rwatson/netperf_merge/sys/pci/if_wb.c#5 (text+ko) ====

@@ -855,7 +855,8 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
-	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
+	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = wb_ioctl;
 	ifp->if_start = wb_start;
 	ifp->if_watchdog = wb_watchdog;
