diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-03-15 14:21:05 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-03-15 14:21:05 +0000 |
commit | 70b6a8119c02ed07bc12918814c950d358cb1885 (patch) | |
tree | 27cbcf88d527d4a8b421eca8e088d73a000fb83f /sys/net | |
parent | 0592710988a69ee8c560a0e065d714f7ff578d43 (diff) | |
download | FreeBSD-src-70b6a8119c02ed07bc12918814c950d358cb1885.zip FreeBSD-src-70b6a8119c02ed07bc12918814c950d358cb1885.tar.gz |
Remove IFF_NEEDSGIANT, a compatibility infrastructure introduced
in FreeBSD 5.x to allow network device drivers to run with Giant
despite the network stack being Giant-free. This significantly
simplifies calls into ioctl() on network interfaces, especially
in the multicast code, as well as eliminates deferred invocation
of interface if_start routines.
Disable the build on device drivers still depending on
IFF_NEEDSGIANT as they no longer compile. They will be removed
in a few weeks if they haven't been made MPSAFE in that time.
Disabled drivers:
if_ar
if_axe
if_aue
if_cdce
if_cue
if_kue
if_ray
if_rue
if_rum
if_sr
if_udav
if_ural
if_zyd
Drivers that were already disabled because of tty changes:
if_ppp
if_sl
Discussed on: arch@
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 66 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 2 | ||||
-rw-r--r-- | sys/net/if_var.h | 11 |
3 files changed, 4 insertions, 75 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index d997949..2f289dc 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -138,7 +138,6 @@ 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 int if_delmulti_locked(struct ifnet *, struct ifmultiaddr *, int); -static void if_start_deferred(void *context, int pending); static void do_link_state_change(void *, int); static int if_getgroup(struct ifgroupreq *, struct ifnet *); static int if_getgroupmembers(struct ifgroupreq *); @@ -582,7 +581,6 @@ if_attach(struct ifnet *ifp) panic ("%s: BUG: if_attach called without if_alloc'd input()\n", ifp->if_xname); - TASK_INIT(&ifp->if_starttask, 0, if_start_deferred, ifp); TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp); IF_AFDATA_LOCK_INIT(ifp); ifp->if_afdata_initialized = 0; @@ -674,9 +672,6 @@ if_attach(struct ifnet *ifp) if (atomic_cmpset_int(&slowtimo_started, 0, 1) && !cold) if_slowtimo(0); } - if (ifp->if_flags & IFF_NEEDSGIANT) - if_printf(ifp, - "WARNING: using obsoleted IFF_NEEDSGIANT flag\n"); } static void @@ -1607,8 +1602,7 @@ if_qflush(struct ifnet *ifp) * 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. + * holding Giant. */ static void if_slowtimo(void *arg) @@ -1741,9 +1735,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | (new_flags &~ IFF_CANTCHANGE); if (ifp->if_ioctl) { - IFF_LOCKGIANT(ifp); (void) (*ifp->if_ioctl)(ifp, cmd, data); - IFF_UNLOCKGIANT(ifp); } getmicrotime(&ifp->if_lastchange); break; @@ -1756,9 +1748,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) return (EOPNOTSUPP); if (ifr->ifr_reqcap & ~ifp->if_capabilities) return (EINVAL); - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, cmd, data); - IFF_UNLOCKGIANT(ifp); if (error == 0) getmicrotime(&ifp->if_lastchange); break; @@ -1830,9 +1820,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, cmd, data); - IFF_UNLOCKGIANT(ifp); if (error == 0) getmicrotime(&ifp->if_lastchange); break; @@ -1848,9 +1836,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) return (EINVAL); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, cmd, data); - IFF_UNLOCKGIANT(ifp); if (error == 0) { getmicrotime(&ifp->if_lastchange); rt_ifmsg(ifp); @@ -1920,9 +1906,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, cmd, data); - IFF_UNLOCKGIANT(ifp); if (error == 0) getmicrotime(&ifp->if_lastchange); break; @@ -1938,9 +1922,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) case SIOCGIFGENERIC: if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, cmd, data); - IFF_UNLOCKGIANT(ifp); break; case SIOCSIFLLADDR: @@ -2168,9 +2150,7 @@ if_setflag(struct ifnet *ifp, int flag, int pflag, int *refcount, int onswitch) } ifr.ifr_flags = ifp->if_flags & 0xffff; ifr.ifr_flagshigh = ifp->if_flags >> 16; - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr); - IFF_UNLOCKGIANT(ifp); if (error) goto recover; /* Notify userland that interface flags have changed */ @@ -2540,9 +2520,7 @@ if_addmulti(struct ifnet *ifp, struct sockaddr *sa, * interface to let them know about it. */ if (ifp->if_ioctl != NULL) { - IFF_LOCKGIANT(ifp); (void) (*ifp->if_ioctl)(ifp, SIOCADDMULTI, 0); - IFF_UNLOCKGIANT(ifp); } if (llsa != NULL) @@ -2601,9 +2579,7 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa) return (ENOENT); if (lastref && ifp->if_ioctl != NULL) { - IFF_LOCKGIANT(ifp); (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0); - IFF_UNLOCKGIANT(ifp); } return (0); @@ -2613,9 +2589,7 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa) * Delete a multicast group membership by group membership pointer. * Network-layer protocol domains must use this routine. * - * It is safe to call this routine if the ifp disappeared. Callers should - * hold IFF_LOCKGIANT() to avoid a LOR in case the hardware needs to be - * reconfigured. + * It is safe to call this routine if the ifp disappeared. */ void if_delmulti_ifma(struct ifmultiaddr *ifma) @@ -2660,9 +2634,7 @@ if_delmulti_ifma(struct ifmultiaddr *ifma) */ IF_ADDR_UNLOCK(ifp); if (lastref && ifp->if_ioctl != NULL) { - IFF_LOCKGIANT(ifp); (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0); - IFF_UNLOCKGIANT(ifp); } } } @@ -2784,7 +2756,6 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len) */ if ((ifp->if_flags & IFF_UP) != 0) { if (ifp->if_ioctl) { - IFF_LOCKGIANT(ifp); ifp->if_flags &= ~IFF_UP; ifr.ifr_flags = ifp->if_flags & 0xffff; ifr.ifr_flagshigh = ifp->if_flags >> 16; @@ -2793,7 +2764,6 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len) ifr.ifr_flags = ifp->if_flags & 0xffff; ifr.ifr_flagshigh = ifp->if_flags >> 16; (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr); - IFF_UNLOCKGIANT(ifp); } #ifdef INET /* @@ -2839,39 +2809,11 @@ if_printf(struct ifnet *ifp, const char * fmt, ...) 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) { - if (ifp->if_flags & IFF_NEEDSGIANT) { - 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; - - GIANT_REQUIRED; - - ifp = context; - (ifp->if_start)(ifp); + (*(ifp)->if_start)(ifp); } /* @@ -2908,7 +2850,7 @@ if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) _IF_ENQUEUE(ifq, m); IF_UNLOCK(ifq); if (ifp != NULL && !active) - if_start(ifp); + (*(ifp)->if_start)(ifp); return (1); } diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index da73543..1e9d956 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -829,9 +829,7 @@ bridge_set_ifcap(struct bridge_softc *sc, struct bridge_iflist *bif, int set) ifr.ifr_reqcap = set; if (ifp->if_capenable != set) { - IFF_LOCKGIANT(ifp); error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); - IFF_UNLOCKGIANT(ifp); if (error) if_printf(sc->sc_ifp, "error setting interface capabilities on %s\n", diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 3ff019f2..7640d78 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -181,7 +181,6 @@ struct ifnet { void *if_afdata[AF_MAX]; int if_afdata_initialized; struct rwlock if_afdata_lock; - struct task if_starttask; /* task for IFF_NEEDSGIANT */ struct task if_linktask; /* task for link change events */ struct mtx if_addr_mtx; /* mutex to protect address lists */ @@ -379,16 +378,6 @@ EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t); #define IF_AFDATA_LOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED) #define IF_AFDATA_UNLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED) -#define IFF_LOCKGIANT(ifp) do { \ - if ((ifp)->if_flags & IFF_NEEDSGIANT) \ - mtx_lock(&Giant); \ -} while (0) - -#define IFF_UNLOCKGIANT(ifp) do { \ - if ((ifp)->if_flags & IFF_NEEDSGIANT) \ - mtx_unlock(&Giant); \ -} while (0) - int if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust); #define IF_HANDOFF(ifq, m, ifp) \ |