From owner-p4-projects@FreeBSD.ORG Wed Mar 26 02:03:12 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0E49A1065674; Wed, 26 Mar 2008 02:03:12 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C24E3106566C for ; Wed, 26 Mar 2008 02:03:11 +0000 (UTC) (envelope-from qingli@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id AA0DA8FC17 for ; Wed, 26 Mar 2008 02:03:11 +0000 (UTC) (envelope-from qingli@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2Q23Buw050064 for ; Wed, 26 Mar 2008 02:03:11 GMT (envelope-from qingli@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2Q23BKe050062 for perforce@freebsd.org; Wed, 26 Mar 2008 02:03:11 GMT (envelope-from qingli@freebsd.org) Date: Wed, 26 Mar 2008 02:03:11 GMT Message-Id: <200803260203.m2Q23BKe050062@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to qingli@freebsd.org using -f From: Qing Li To: Perforce Change Reviews Cc: Subject: PERFORCE change 138573 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Mar 2008 02:03:12 -0000 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: