tech-kern 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]



http://marc.info/?t=141670552700001&r=1&w=2

Following the ideas raised in that thread:

- Allocate callout_t dynamically.  struct ifnet only has a pointer to struct
  callout, which will not be read by netstat(1) anyway.

- Prefer the name "slowtimo" to "watchdog", because those callbacks do a
  little more than what "watchdog" suggests.

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