diff --git a/sys/net/if.c b/sys/net/if.c index c1333b8..9fad0b0 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -168,8 +168,6 @@ static kmutex_t if_clone_mtx; static struct ifaddr ** ifnet_addrs = NULL; -static callout_t if_slowtimo_ch; - struct ifnet *lo0ifp; int ifqmaxlen = IFQ_MAXLEN; @@ -194,6 +192,7 @@ static void ifnet_lock_exit(struct ifnet_lock *); static void if_detach_queues(struct ifnet *, struct ifqueue *); static void sysctl_sndq_setup(struct sysctllog **, const char *, struct ifaltq *); +static void if_slowtimo(void *); #if defined(INET) || defined(INET6) static void sysctl_net_pktq_setup(struct sysctllog **, int); @@ -235,9 +234,6 @@ ifinit(void) sysctl_net_pktq_setup(NULL, PF_INET6); #endif - callout_init(&if_slowtimo_ch, 0); - if_slowtimo(NULL); - if_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK, if_listener_cb, NULL); @@ -337,7 +333,7 @@ if_nullstop(struct ifnet *ifp, int disable) } void -if_nullwatchdog(struct ifnet *ifp) +if_nullslowtimo(struct ifnet *ifp) { /* Nothing. */ @@ -637,6 +633,12 @@ if_attach(ifnet_t *ifp) /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); + + if (ifp->if_slowtimo != NULL) { + callout_init(&ifp->if_slowtimo_ch, 0); + callout_setfunc(&ifp->if_slowtimo_ch, if_slowtimo, ifp); + if_slowtimo(ifp); + } } void @@ -687,7 +689,7 @@ if_deactivate(struct ifnet *ifp) ifp->if_ioctl = if_nullioctl; ifp->if_init = if_nullinit; ifp->if_stop = if_nullstop; - ifp->if_watchdog = if_nullwatchdog; + ifp->if_slowtimo = if_nullslowtimo; ifp->if_drain = if_nulldrain; /* No more packets may be enqueued. */ @@ -736,6 +738,11 @@ if_detach(struct ifnet *ifp) s = splnet(); + if (ifp->if_slowtimo != NULL) { + callout_halt(&ifp->if_slowtimo_ch, NULL); + callout_destroy(&ifp->if_slowtimo_ch); + } + /* * Do an if_down() to give protocols a chance to do something. */ @@ -1493,24 +1500,23 @@ if_up(struct ifnet *ifp) } /* - * Handle interface watchdog timer routines. Called - * from softclock, we decrement timers (if set) and + * Handle interface slowtimo timer routine. Called + * from softclock, we decrement timer (if set) and * call the appropriate interface routine on expiration. */ -void +static void if_slowtimo(void *arg) { - struct ifnet *ifp; + struct ifnet *ifp = arg; int s = splnet(); - IFNET_FOREACH(ifp) { - if (ifp->if_timer == 0 || --ifp->if_timer) - continue; - if (ifp->if_watchdog != NULL) - (*ifp->if_watchdog)(ifp); - } + KASSERT(ifp->if_slowtimo != NULL); + + if (ifp->if_timer != 0 && --ifp->if_timer == 0) + (*ifp->if_slowtimo)(ifp); + splx(s); - callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ, if_slowtimo, NULL); + callout_schedule(&ifp->if_slowtimo_ch, hz / IFNET_SLOWHZ); } /* diff --git a/sys/net/if.h b/sys/net/if.h index 65eb7ad..78bc1aa 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -214,6 +214,7 @@ struct ifnet_lock; #ifdef _KERNEL #include #include +#include struct ifnet_lock { kmutex_t il_lock; /* Protects the critical section. */ @@ -253,7 +254,7 @@ typedef struct ifnet { int if_pcount; /* number of promiscuous listeners */ struct bpf_if *if_bpf; /* packet filter structure */ u_short if_index; /* numeric abbreviation for this if */ - short if_timer; /* time 'til if_watchdog called */ + short if_timer; /* time 'til if_slowtimo called */ short if_flags; /* up/down, broadcast, etc. */ short if__pad1; /* be nice to m68k ports */ struct if_data if_data; /* statistics and other data about if */ @@ -274,8 +275,9 @@ typedef struct ifnet { (struct ifnet *); void (*if_stop) /* stop routine */ (struct ifnet *, int); - void (*if_watchdog) /* timer routine */ + void (*if_slowtimo) /* timer routine */ (struct ifnet *); +#define if_watchdog if_slowtimo void (*if_drain) /* routine to release resources */ (struct ifnet *); struct ifaltq if_snd; /* output queue (includes altq) */ @@ -341,6 +343,9 @@ typedef struct ifnet { const struct sockaddr *); int (*if_setflags)(struct ifnet *, const short); struct ifnet_lock *if_ioctl_lock; +#ifdef _KERNEL /* XXX kvm(3) */ + callout_t if_slowtimo_ch; +#endif } ifnet_t; #define if_mtu if_data.ifi_mtu @@ -867,7 +872,6 @@ void if_purgeaddrs(struct ifnet *, int, void (*)(struct ifaddr *)); void if_detach(struct ifnet *); void if_down(struct ifnet *); void if_link_state_change(struct ifnet *, int); -void if_slowtimo(void *); void if_up(struct ifnet *); int ifconf(u_long, void *); void ifinit(void); @@ -926,7 +930,8 @@ void if_nullstart(struct ifnet *); int if_nullioctl(struct ifnet *, u_long, void *); int if_nullinit(struct ifnet *); void if_nullstop(struct ifnet *, int); -void if_nullwatchdog(struct ifnet *); +void if_nullslowtimo(struct ifnet *); +#define if_nullwatchdog if_nullslowtimo void if_nulldrain(struct ifnet *); #else struct if_nameindex {