PERFORCE change 153315 for review

Qing Li qingli at FreeBSD.org
Fri Nov 21 17:30:21 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=153315

Change 153315 by qingli at FreeBSD-newarp on 2008/11/22 01:29:34

	
	1. fixed the callout issue where enabling callout code
	   for timing out entries would trigger kernel panic
	2. introduced a mutex for handling callout
	3. fixed the interface table locking issue, the locking
	   code was actually disabled (oops!)
	4. fixed the recursive-lock panic, typo (oops!)
	
	Unit testing: 
	1. running "ping x.x.x.255" and "ping6 fe80::???"
	   continuous that used to cause kernel panics immediately
	2. continuous running "netperf" TCP_STREAM tests, which
	   also triggered kernel panics immediately

Affected files ...

.. //depot/projects/arp-v2/src/sys/net/if_llatbl.c#3 edit
.. //depot/projects/arp-v2/src/sys/net/if_llatbl.h#2 edit
.. //depot/projects/arp-v2/src/sys/net/if_var.h#7 edit
.. //depot/projects/arp-v2/src/sys/net/route.c#11 edit
.. //depot/projects/arp-v2/src/sys/netinet/if_ether.c#14 edit
.. //depot/projects/arp-v2/src/sys/netinet6/nd6.c#7 edit
.. //depot/projects/arp-v2/src/sys/netinet6/nd6_nbr.c#6 edit

Differences ...

==== //depot/projects/arp-v2/src/sys/net/if_llatbl.c#3 (text+ko) ====

@@ -185,6 +185,7 @@
 	KASSERT(lle != NULL, ("%s: lle is NULL", __func__));
 
 	LIST_REMOVE(lle, lle_next);
+	IF_LLE_LOCK_DESTROY(lle);
 	if (lle->la_hold)
 		m_freem(lle->la_hold);
 	uma_zfree(llezone, lle);
@@ -362,6 +363,10 @@
 			log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
 			return (NULL);
 		}
+
+		IF_LLE_LOCK_INIT(lle);
+		callout_init_mtx(&lle->la_timer, &lle->lle_mtx, 0);
+
 		/* qing
 		 * For IPv4 this will trigger "arpresolve" to generate
 		 * an ARP request 

==== //depot/projects/arp-v2/src/sys/net/if_llatbl.h#2 (text+ko) ====

@@ -60,6 +60,7 @@
 		struct callout	ln_timer_ch;
 		struct callout  la_timer;
 	} lle_timer;
+	struct mtx		 lle_mtx;	/* mutex for lle entry */
 };
 
 #define ln_timer_ch	lle_timer.ln_timer_ch
@@ -97,6 +98,12 @@
 
 #define LLATBL_HASH(key, mask) (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
 
+#define	IF_LLE_LOCK_INIT(lle)	mtx_init(&(lle)->lle_mtx,		\
+				    "if_llentry_mtx", NULL, MTX_DEF | MTX_RECURSE)
+#define	IF_LLE_LOCK_DESTROY(lle)	mtx_destroy(&(lle)->lle_mtx)
+#define	IF_LLE_LOCK(lle)	mtx_lock(&(lle)->lle_mtx)
+#define	IF_LLE_UNLOCK(lle)	mtx_unlock(&(lle)->lle_mtx)
+
 extern struct llentry	 *lla_lookup(struct ifnet *ifp, u_int flags, struct sockaddr *l3addr);
 extern int		 lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info);
 extern int		 llentry_free(struct llentry *lle);

==== //depot/projects/arp-v2/src/sys/net/if_var.h#7 (text+ko) ====

@@ -244,13 +244,8 @@
 #define	IF_LLTBLS_LOCK_INIT(if)	mtx_init(&(if)->if_lltbls_mtx,		\
 				    "if_lltbls_mtx", NULL, MTX_DEF | MTX_RECURSE)
 #define	IF_LLTBLS_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_lltbls_mtx)
-#if 0
 #define	IF_LLTBLS_LOCK(if)	mtx_lock(&(if)->if_lltbls_mtx)
 #define	IF_LLTBLS_UNLOCK(if)	mtx_unlock(&(if)->if_lltbls_mtx)
-#else
-#define	IF_LLTBLS_LOCK(if)	
-#define	IF_LLTBLS_UNLOCK(if)	
-#endif
 #define	IF_LLTBLS_LOCK_ASSERT(if)	mtx_assert(&(if)->if_lltbls_mtx, MA_OWNED)
 
 

==== //depot/projects/arp-v2/src/sys/net/route.c#11 (text+ko) ====

@@ -41,6 +41,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/syslog.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
@@ -379,12 +380,7 @@
 	 */
 	RT_REMREF(rt);
 	if (rt->rt_refcnt > 0) {
-		printf("%s: %p has %lu refs\t", __func__, rt, rt->rt_refcnt);
-		printf("route dst = %s", inet_ntoa(((struct sockaddr_in *)rt_key(rt))->sin_addr));
-		if (rt->rt_flags & RTF_GATEWAY)
-			printf(", gw = %s\n", inet_ntoa(((struct sockaddr_in *)rt->rt_gateway)->sin_addr));
-		else
-			printf("\n");
+		log(LOG_DEBUG, "%s: %p has %lu refs\t", __func__, rt, rt->rt_refcnt);
 		goto done;
 	}
 
@@ -1613,7 +1609,6 @@
 					 * we don't actually need a reference.
 					 */
 					RT_REMREF(rt);
-					printf("rtref = %ld\n", rt->rt_refcnt);
 				}
 				RT_UNLOCK(rt);
 			}

==== //depot/projects/arp-v2/src/sys/netinet/if_ether.c#14 (text+ko) ====

@@ -149,12 +149,18 @@
 	struct ifnet *ifp;
 	struct llentry   *lle = (struct llentry *)arg;
 
+	if (lle == NULL) {
+		panic("arptimer: NULL entry!\n");
+		return;
+	}
 	ifp = lle->lle_tbl->llt_ifp;
 	IF_LLTBLS_LOCK(ifp);
 	if ((lle->la_flags & LLE_DELETED) &&
 	    !(lle->la_flags & LLE_STATIC)) {
-		callout_stop(&lle->la_timer);
-		(void)llentry_free(lle);
+		if (!callout_pending(&lle->la_timer)  &&
+		    (callout_active(&lle->la_timer))) {
+			(void)llentry_free(lle);
+		}
 	}
 	IF_LLTBLS_UNLOCK(ifp);
 }
@@ -278,8 +284,6 @@
 		m_freem(m);
 		return (EINVAL);
 	} 
-	if (flags & LLE_CREATE)
-		callout_init(&la->la_timer, 0);
 
 	if (la->la_flags & LLE_VALID &&
 	    (la->la_flags & LLE_STATIC || la->la_expire > time_uptime)) {
@@ -574,9 +578,6 @@
 			goto reply;
 		}
 
-		if (flag & LLE_CREATE)
-			callout_init(&la->la_timer, 0);
-
 		if (la->la_flags & LLE_VALID &&
 		    bcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
 			if (la->la_flags & LLE_STATIC) {
@@ -743,7 +744,6 @@
 	IF_LLTBLS_LOCK(ifp);
 	lle = lla_lookup(ifp, (LLE_CREATE | LLE_IFADDR | LLE_STATIC),
 	    (struct sockaddr *)IA_SIN(ifa));
-	callout_init(&lle->la_timer, 0);
 	IF_LLTBLS_UNLOCK(ifp);
 	if (lle == NULL)
 		log(LOG_INFO, "arp_ifinit: cannot create arp "

==== //depot/projects/arp-v2/src/sys/netinet6/nd6.c#7 (text+ko) ====

@@ -1043,7 +1043,7 @@
 {
 	INIT_VNET_INET6(curvnet);
 	struct llentry *ln;
-/*	struct ifnet *ifp = rt->rt_ifp;*/
+	struct ifnet *ifp = rt->rt_ifp;
 
 	if (dst6 == NULL)
 		return;

==== //depot/projects/arp-v2/src/sys/netinet6/nd6_nbr.c#6 (text+ko) ====

@@ -879,7 +879,7 @@
 			nd6_output(ifp, ifp, m_hold, &ln->l3_addr6, NULL);
 		}
 	}
-	IF_LLTBLS_LOCK(ifp);
+	IF_LLTBLS_UNLOCK(ifp);
 
  freeit:
 	m_freem(m);


More information about the p4-projects mailing list