Module Name:    src
Committed By:   ozaki-r
Date:           Wed Nov 26 07:43:04 UTC 2014

Modified Files:
        src/sys/net: if.c if.h

Log Message:
Create if_slowtimo (if_watchdog) callout for each interface

This change is to obviate the need to run if_slowtimo callbacks that
may sleep inside IFNET_FOREACH. And also by this change we can turn
on MPSAFE of callouts individually.

Discussed with uebayasi@ and riastradh@.


To generate a diff of this commit:
cvs rdiff -u -r1.295 -r1.296 src/sys/net/if.c
cvs rdiff -u -r1.177 -r1.178 src/sys/net/if.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.295 src/sys/net/if.c:1.296
--- src/sys/net/if.c:1.295	Wed Nov 26 07:22:05 2014
+++ src/sys/net/if.c	Wed Nov 26 07:43:04 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.295 2014/11/26 07:22:05 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.296 2014/11/26 07:43:04 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.295 2014/11/26 07:22:05 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.296 2014/11/26 07:43:04 ozaki-r Exp $");
 
 #include "opt_inet.h"
 
@@ -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;
 
@@ -236,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);
 
@@ -638,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
@@ -737,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.
 	 */
@@ -1494,24 +1500,23 @@ if_up(struct ifnet *ifp)
 }
 
 /*
- * Handle interface slowtimo 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.
  */
 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_slowtimo != NULL)
-			(*ifp->if_slowtimo)(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);
 }
 
 /*

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.177 src/sys/net/if.h:1.178
--- src/sys/net/if.h:1.177	Wed Nov 26 07:22:05 2014
+++ src/sys/net/if.h	Wed Nov 26 07:43:04 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.177 2014/11/26 07:22:05 ozaki-r Exp $	*/
+/*	$NetBSD: if.h,v 1.178 2014/11/26 07:43:04 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -214,6 +214,7 @@ struct ifnet_lock;
 #ifdef _KERNEL
 #include <sys/condvar.h>
 #include <sys/percpu.h>
+#include <sys/callout.h>
 
 struct ifnet_lock {
 	kmutex_t il_lock;	/* Protects the critical section. */
@@ -342,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

Reply via email to