Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Mar 2008 02:03:11 GMT
From:      Qing Li <qingli@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 138573 for review
Message-ID:  <200803260203.m2Q23BKe050062@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=138573

Change 138573 by qingli@FreeBSD-newarp on 2008/03/26 02:03:00

	fixed the "lock not released" panic

Affected files ...

.. //depot/projects/qingli_mpath/src/sys/net/radix_mpath.c#3 edit
.. //depot/projects/qingli_mpath/src/sys/net/radix_mpath.h#2 edit
.. //depot/projects/qingli_mpath/src/sys/net/route.c#4 edit

Differences ...

==== //depot/projects/qingli_mpath/src/sys/net/radix_mpath.c#3 (text+ko) ====

@@ -103,7 +103,7 @@
 	rn = (struct radix_node *)rt;
 	do {
 		rt = (struct rtentry *)rn;
-		/*
+		/* qingli:
 		 * we are removing an address alias that has 
 		 * the same prefix as another address
 		 * we need to compare the interface address because
@@ -124,6 +124,10 @@
 	return (struct rtentry *)rn;
 }
 
+/* qingli:
+ * go through the chain and unlink "rt" from the list
+ * the caller will free "rt"
+ */
 int
 rt_mpath_deldup(headrt, rt)
         struct rtentry *headrt;
@@ -304,7 +308,7 @@
 	rtfree(ro->ro_rt);
 	ro->ro_rt = (struct rtentry *)rn;
 	RT_LOCK(ro->ro_rt);
-	ro->ro_rt->rt_refcnt++;
+	RT_ADDREF(ro->ro_rt);
 	RT_UNLOCK(ro->ro_rt);
 }
 

==== //depot/projects/qingli_mpath/src/sys/net/radix_mpath.h#2 (text+ko) ====

@@ -47,29 +47,18 @@
 struct radix_node *rn_mpath_next __P((struct radix_node *));
 int rn_mpath_count __P((struct radix_node *));
 struct rtentry *rt_mpath_matchgate __P((struct rtentry *, struct sockaddr *));
-#ifdef __OpenBSD__
-int rt_mpath_conflict __P((struct radix_node_head *, struct rtentry *,
-	struct sockaddr *, int));
-#else
 int rt_mpath_conflict __P((struct radix_node_head *, struct rtentry *,
 	struct sockaddr *));
-#endif
 void rtalloc_mpath __P((struct route *, int));
 struct radix_node *rn_mpath_lookup __P((void *, void *,
 	struct radix_node_head *));
 int rt_mpath_deldup __P((struct rtentry *, struct rtentry *));
-#ifdef __FreeBSD__
 int	rn4_mpath_inithead __P((void **, int));
 int	rn6_mpath_inithead __P((void **, int));
-#else
-int	rn_mpath_inithead __P((void **, int));
-#endif
 
-#ifdef __FreeBSD__
 /* for compatibility with NetBSD */
 #define rn_p rn_parent
 #define rn_b rn_bit
-#endif
 
 #endif
 

==== //depot/projects/qingli_mpath/src/sys/net/route.c#4 (text+ko) ====

@@ -720,11 +720,19 @@
 			rt = rt_mpath_matchgate(rt, gateway);
 			if (!rt)
 				senderr(ESRCH);
+			/*
+			 * this is the first entry in the chain
+			 */
 			if (rto == rt) {
 				rn = rn_mpath_next((struct radix_node *)rt);
+				/*
+				 * there is another entry, now it's active
+				 */
 				if (rn) {
 					rto = RNTORT(rn);
+					RT_LOCK(rto);
 					rto->rt_flags |= RTF_UP;
+					RT_UNLOCK(rto);
 				} else if (rt->rt_flags & RTF_GATEWAY) {
 					/*
 					 * For gateway routes, we need to make sure that we 
@@ -737,8 +745,15 @@
 					    memcmp(rt->rt_gateway, gateway, gateway->sa_len)))
 						senderr(ESRCH);
 				}
+				/*
+				 * use the normal delete code to remove
+				 * the first entry
+				 */
 				goto normal_rtdel;
 			}
+			/*
+			 * if the entry is 2nd and on up
+			 */
 			if (!rt_mpath_deldup(rto, rt))
 				panic ("rtrequest1: rt_mpath_deldup");
 			RT_LOCK(rt);
@@ -877,11 +892,13 @@
 		if (rn_mpath_capable(rnh) &&
 			rt_mpath_conflict(rnh, rt, netmask)) {
 			if (rt->rt_gwroute)
-				rtfree(rt->rt_gwroute);
+				RTFREE(rt->rt_gwroute);
 			if (rt->rt_ifa) {
 				IFAFREE(rt->rt_ifa);
 			}
 			Free(rt_key(rt));
+			RT_LOCK_DESTROY(rt);
+			uma_zfree(rtzone, rt);
 			senderr(EEXIST);
 		}
 #endif
@@ -1230,7 +1247,7 @@
 	struct mbuf *m = NULL;
 	struct rtentry *rt = NULL;
 	struct rt_addrinfo info;
-	int error;
+	int error=0;
 
 	if (flags & RTF_HOST) {
 		dst = ifa->ifa_dstaddr;
@@ -1291,12 +1308,12 @@
 			}
 		}
 		else
-#else		
+#endif
 		error = ((rn = rnh->rnh_lookup(dst, netmask, rnh)) == NULL ||
 		    (rn->rn_flags & RNF_ROOT) ||
 		    RNTORT(rn)->rt_ifa != ifa ||
 		    !sa_equal((struct sockaddr *)rn->rn_key, dst));
-#endif
+
 		RADIX_NODE_HEAD_UNLOCK(rnh);
 		if (error) {
 bad:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803260203.m2Q23BKe050062>