tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: struct ifnet and ifaddr handling [was: Re: Making global variables of if.c MPSAFE]
On Mon, Nov 24, 2014 at 11:23 AM, Masao Uebayashi <uebayasi%gmail.com@localhost> wrote:
> http://marc.info/?t=141670552700001&r=1&w=2
>
> Following the ideas raised in that thread:
Thank you for the information.
>
> - Allocate callout_t dynamically. struct ifnet only has a pointer to struct
> callout, which will not be read by netstat(1) anyway.
Yes, it works (actually I'm doing it in refcount). I worried that
using malloc/free makes MP-ifying difficult and wanted another way
if there is.
>
> - Prefer the name "slowtimo" to "watchdog", because those callbacks do a
> little more than what "watchdog" suggests.
Sure.
ozaki-r
>
> Index: sys/net/if.c
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if.c,v
> retrieving revision 1.293
> diff -p -u -r1.293 if.c
> --- sys/net/if.c 17 Nov 2014 13:58:53 -0000 1.293
> +++ sys/net/if.c 24 Nov 2014 01:49:14 -0000
> @@ -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
> 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 disab
> }
>
> void
> -if_nullwatchdog(struct ifnet *ifp)
> +if_nullslowtimo(struct ifnet *ifp)
> {
>
> /* Nothing. */
> @@ -637,6 +633,13 @@ if_attach(ifnet_t *ifp)
>
> /* Announce the interface. */
> rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
> +
> + if (ifp->if_slowtimo != NULL) {
> + ifp->if_slowtimo_ch =
> + kmem_zalloc(sizeof(*ifp->if_slowtimo_ch), KM_SLEEP);
> + callout_init(ifp->if_slowtimo_ch, 0);
> + if_slowtimo(ifp);
> + }
> }
>
> void
> @@ -687,7 +690,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 +739,12 @@ 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);
> + kmem_free(ifp->if_slowtimo_ch, sizeof(*ifp->if_slowtimo_ch));
> + }
> +
> /*
> * Do an if_down() to give protocols a chance to do something.
> */
> @@ -1493,24 +1502,23 @@ if_up(struct ifnet *ifp)
> }
>
> /*
> - * Handle interface watchdog timer routines. Called
> - * from softclock, we decrement timers (if set) and
> + * Handle interface slow timeout 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_reset(ifp->if_slowtimo_ch, hz / IFNET_SLOWHZ, if_slowtimo, ifp);
> }
>
> /*
> Index: sys/net/if.h
> ===================================================================
> RCS file: /cvsroot/src/sys/net/if.h,v
> retrieving revision 1.175
> diff -p -u -r1.175 if.h
> --- sys/net/if.h 9 Sep 2014 20:16:12 -0000 1.175
> +++ sys/net/if.h 24 Nov 2014 01:49:14 -0000
> @@ -244,6 +244,7 @@ TAILQ_HEAD(ifnet_head, ifnet); /* the a
>
> struct bridge_softc;
> struct bridge_iflist;
> +struct callout;
>
> typedef struct ifnet {
> void *if_softc; /* lower-level data for this if */
> @@ -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,7 @@ typedef struct ifnet {
> const struct sockaddr *);
> int (*if_setflags)(struct ifnet *, const short);
> struct ifnet_lock *if_ioctl_lock;
> + struct callout *if_slowtimo_ch;
> } ifnet_t;
>
> #define if_mtu if_data.ifi_mtu
> @@ -867,7 +870,6 @@ void if_purgeaddrs(struct ifnet *, int,
> 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 +928,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 {
Home |
Main Index |
Thread Index |
Old Index