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 #include #include +#include #include #include #include @@ -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 /* XXX */ #include /* XXX */ #include /* XXX */ +#include #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;