Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Nov 2014 00:07:07 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r274336 - in projects/routing/sys: net netinet netinet6 netpfil/ipfw nfs
Message-ID:  <201411100007.sAA077TD094634@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Mon Nov 10 00:07:06 2014
New Revision: 274336
URL: https://svnweb.freebsd.org/changeset/base/274336

Log:
  Switch route radix to dual-lock model:
  use rmlock for data patch access, and config rwlock
  for conrol plane processing. Route table changes require
  bock locks held.

Modified:
  projects/routing/sys/net/route.c
  projects/routing/sys/net/route_internal.h
  projects/routing/sys/net/rt_nhops.c
  projects/routing/sys/net/rtsock.c
  projects/routing/sys/netinet/in_rmx.c
  projects/routing/sys/netinet6/nd6_rtr.c
  projects/routing/sys/netpfil/ipfw/ip_fw_table_algo.c
  projects/routing/sys/nfs/bootp_subr.c

Modified: projects/routing/sys/net/route.c
==============================================================================
--- projects/routing/sys/net/route.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/net/route.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -44,6 +44,9 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/syslog.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/rmlock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
@@ -281,7 +284,8 @@ rt_table_init(int offset)
 	rh->rmhead.head.s.mask_nodes = rh->rmhead.mask_nodes;
 
 	/* Init locks */
-	rw_init(&rh->rib_lock, "rib head");
+	rm_init(&rh->rib_lock, "rib head run");
+	rw_init(&rh->rib_cfglock, "rib head cfg");
 
 	/* Finally, set base callbacks */
 	rh->rnh_addaddr = rn_addroute;
@@ -299,7 +303,8 @@ rt_table_destroy(struct rib_head *rh)
 {
 
 	/* Assume table is already empty */
-	rw_destroy(&rh->rib_lock);
+	rw_destroy(&rh->rib_cfglock);
+	rm_destroy(&rh->rib_lock);
 	free(rh, M_RTABLE);
 }
 
@@ -365,6 +370,7 @@ rtalloc1_fib(struct sockaddr *dst, int r
 	struct rt_addrinfo info;
 	int err = 0, msgtype = RTM_MISS;
 	int needlock;
+	RIB_LOCK_READER;
 
 	KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
 	rh = rt_tables_get_rnh(fibnum, dst->sa_family);
@@ -612,11 +618,13 @@ rtredirect_fib(struct sockaddr *dst,
 			 * add the key and gateway (in one malloc'd chunk).
 			 */
 			RT_UNLOCK(rt);
+			RIB_CFG_WLOCK(rh);
 			RIB_WLOCK(rh);
 			RT_LOCK(rt);
 			rt_setgate(rt, rt_key(rt), gateway);
 			gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
 			RIB_WUNLOCK(rh);
+			RIB_CFG_WUNLOCK(rh);
 			EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
 			RTFREE_LOCKED(gwrt);
 		}
@@ -794,9 +802,12 @@ rt_foreach_fib(int af, rt_setwarg_t *set
 			if (setwa_f != NULL)
 				setwa_f(rh, fibnum, i, arg);
 
+			RIB_CFG_WLOCK(rh);
+			/* Do runtime locking for now */
 			RIB_WLOCK(rh);
 			rh->rnh_walktree(&rh->head, (walktree_f_t *)wa_f, arg);
 			RIB_WUNLOCK(rh);
+			RIB_CFG_WUNLOCK(rh);
 			continue;
 		}
 
@@ -807,9 +818,12 @@ rt_foreach_fib(int af, rt_setwarg_t *set
 			if (setwa_f != NULL)
 				setwa_f(rh, fibnum, i, arg);
 
+			RIB_CFG_WLOCK(rh);
 			RIB_WLOCK(rh);
+			/* Do runtime locking for now */
 			rh->rnh_walktree(&rh->head, (walktree_f_t *)wa_f, arg);
 			RIB_WUNLOCK(rh);
+			RIB_CFG_WUNLOCK(rh);
 		}
 	}
 }
@@ -1203,9 +1217,10 @@ rtrequest1_fib(int req, struct rt_addrin
 		return (EAFNOSUPPORT);
 	needlock = ((flags & RTF_RNH_LOCKED) == 0);
 	flags &= ~RTF_RNH_LOCKED;
-	if (needlock)
+	if (needlock) {
+		RIB_CFG_WLOCK(rh);
 		RIB_WLOCK(rh);
-	else
+	} else
 		RIB_LOCK_ASSERT(rh);
 	/*
 	 * If we are adding a host route then we don't want to put
@@ -1453,8 +1468,10 @@ rtrequest1_fib(int req, struct rt_addrin
 		error = EOPNOTSUPP;
 	}
 bad:
-	if (needlock)
+	if (needlock) {
 		RIB_WUNLOCK(rh);
+		RIB_CFG_WUNLOCK(rh);
+	}
 	return (error);
 #undef senderr
 }
@@ -1730,7 +1747,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 			if (rh == NULL)
 				/* this table doesn't exist but others might */
 				continue;
-			RIB_RLOCK(rh);
+			RIB_CFG_RLOCK(rh);
 			rn = rh->rnh_lookup(dst, netmask, &rh->head);
 #ifdef RADIX_MPATH
 			if (rn_mpath_capable(rh)) {
@@ -1756,7 +1773,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 			error = (rn == NULL ||
 			    (rn->rn_flags & RNF_ROOT) ||
 			    RNTORT(rn)->rt_ifa != ifa);
-			RIB_RUNLOCK(rh);
+			RIB_CFG_RUNLOCK(rh);
 			if (error) {
 				/* this is only an error if bad on ALL tables */
 				continue;
@@ -1789,6 +1806,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 			 * interface prefix.
 			 */
 			rh = rt_tables_get_rnh(fibnum, dst->sa_family);
+			RIB_CFG_WLOCK(rh);
 			RIB_WLOCK(rh);
 
 			/* Delete old prefix */
@@ -1804,6 +1822,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 			}
 
 			RIB_WUNLOCK(rh);
+			RIB_CFG_WUNLOCK(rh);
 		}
 
 

Modified: projects/routing/sys/net/route_internal.h
==============================================================================
--- projects/routing/sys/net/route_internal.h	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/net/route_internal.h	Mon Nov 10 00:07:06 2014	(r274336)
@@ -32,6 +32,7 @@
 
 struct rib_head {
 	struct radix_head head;
+	struct rmlock	rib_lock;	/* data path lock */
 	rn_matchaddr_f_t	*rnh_matchaddr;	/* longest match for sockaddr */
 	rn_addaddr_f_t	*rnh_addaddr;	/* add based on sockaddr*/
 	rn_deladdr_f_t	*rnh_deladdr;	/* remove based on sockaddr */
@@ -40,16 +41,24 @@ struct rib_head {
 	rn_walktree_from_t	*rnh_walktree_from; /* traverse tree below a */
 	rn_close_t	*rnh_close;	/*do something when the last ref drops*/
 	struct	radix_node rnh_nodes[3];	/* empty tree for common case */
-	struct	rwlock rib_lock;		/* locks entire radix tree */
+	struct	rwlock rib_cfglock;		/* config lock */
 	struct radix_mask_head rmhead;	/* masks radix head */
 };
 
-#define	RIB_RLOCK(rh)	rw_rlock(&(rh)->rib_lock)
-#define	RIB_RUNLOCK(rh)	rw_runlock(&(rh)->rib_lock)
-#define	RIB_WLOCK(rh)	rw_wlock(&(rh)->rib_lock)
-#define	RIB_WUNLOCK(rh)	rw_wunlock(&(rh)->rib_lock)
-#define	RIB_LOCK_ASSERT(rh)	rw_assert(&(rh)->rib_lock, RA_LOCKED)
-#define	RIB_WLOCK_ASSERT(rh)	rw_assert(&(rh)->rib_lock, RA_WLOCKED)
+#define	RIB_RLOCK(rh)		rm_rlock(&(rh)->rib_lock, &tracker)
+#define	RIB_RUNLOCK(rh)		rm_runlock(&(rh)->rib_lock, &tracker)
+#define	RIB_WLOCK(rh)		rm_wlock(&(rh)->rib_lock)
+#define	RIB_WUNLOCK(rh)		rm_wunlock(&(rh)->rib_lock)
+#define	RIB_WLOCK_ASSERT(rh)	rm_assert(&(rh)->rib_lock, RA_WLOCKED)
+#define	RIB_LOCK_READER		struct rm_priotracker tracker
+#define	RIB_LOCK_ASSERT(rh)	rm_assert(&(rh)->rib_lock, RA_LOCKED)
+
+#define	RIB_CFG_RLOCK(rh)		rw_rlock(&(rh)->rib_cfglock)
+#define	RIB_CFG_RUNLOCK(rh)		rw_runlock(&(rh)->rib_cfglock)
+#define	RIB_CFG_WLOCK(rh)		rw_wlock(&(rh)->rib_cfglock)
+#define	RIB_CFG_WUNLOCK(rh)		rw_wunlock(&(rh)->rib_cfglock)
+#define	RIB_CFG_LOCK_ASSERT(rh)		rw_assert(&(rh)->rib_cfglock, RA_LOCKED)
+#define	RIB_CFG_WLOCK_ASSERT(rh)	rw_assert(&(rh)->rib_cfglock, RA_WLOCKED)
 
 struct rib_head *rt_table_init(int offset);
 void rt_table_destroy(struct rib_head *rh);

Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/net/rt_nhops.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -40,6 +40,9 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/syslog.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/rmlock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
@@ -262,8 +265,8 @@ fib4_lookup_prepend(uint32_t fibnum, str
 	struct in_addr gw;
 	struct ether_header *eh;
 	int error, flags;
-	//uint32_t flowid;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_prepend: bad fibnum"));
 	rh = rt_tables_get_rnh(fibnum, AF_INET);
@@ -506,6 +509,7 @@ fib4_lookup_nh_basic(uint32_t fibnum, st
 	struct radix_node *rn;
 	struct sockaddr_in sin;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_basic: bad fibnum"));
 	rh = rt_tables_get_rnh(fibnum, AF_INET);
@@ -542,6 +546,7 @@ fib4_lookup_nh_ifp(uint32_t fibnum, stru
 	struct radix_node *rn;
 	struct sockaddr_in sin;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ifp: bad fibnum"));
 	rh = rt_tables_get_rnh(fibnum, AF_INET);
@@ -587,6 +592,7 @@ fib4_lookup_nh_ext(uint32_t fibnum, stru
 	struct radix_node *rn;
 	struct sockaddr_in sin;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum"));
 	rh = rt_tables_get_rnh(fibnum, AF_INET);
@@ -632,6 +638,7 @@ rib4_lookup_nh_ext(uint32_t fibnum, stru
 	struct radix_node *rn;
 	struct sockaddr_in sin;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	KASSERT((fibnum < rt_numfibs), ("rib4_lookup_nh_ext: bad fibnum"));
 	rh = rt_tables_get_rnh(fibnum, AF_INET);
@@ -757,6 +764,7 @@ fib6_lookup_prepend(uint32_t fibnum, str
 	struct rtentry *rte;
 	struct ifnet *lifp;
 	struct ether_header *eh;
+	RIB_LOCK_READER;
 	uint32_t flags;
 	int error;
 
@@ -1129,6 +1137,7 @@ fib6_lookup_nh_ifp(uint32_t fibnum, stru
 	struct radix_node *rn;
 	struct sockaddr_in6 sin6;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
 		/* Do not lookup link-local addresses in rtable */
@@ -1172,6 +1181,7 @@ fib6_lookup_nh_basic(uint32_t fibnum, st
 	struct radix_node *rn;
 	struct sockaddr_in6 sin6;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
 		/* Do not lookup link-local addresses in rtable */
@@ -1222,6 +1232,7 @@ fib6_lookup_nh_ext(uint32_t fibnum, stru
 	struct radix_node *rn;
 	struct sockaddr_in6 sin6;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
 		/* Do not lookup link-local addresses in rtable */
@@ -1275,6 +1286,7 @@ rib6_lookup_nh_ext(uint32_t fibnum, stru
 	struct radix_node *rn;
 	struct sockaddr_in6 sin6;
 	struct rtentry *rte;
+	RIB_LOCK_READER;
 
 	if (IN6_IS_SCOPE_LINKLOCAL(dst)) {
 		/* Do not lookup link-local addresses in rtable */

Modified: projects/routing/sys/net/rtsock.c
==============================================================================
--- projects/routing/sys/net/rtsock.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/net/rtsock.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -39,6 +39,9 @@
 #include <sys/kernel.h>
 #include <sys/domain.h>
 #include <sys/lock.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/rmlock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/priv.h>
@@ -703,7 +706,7 @@ route_output(struct mbuf *m, struct sock
 		if (rh == NULL)
 			senderr(EAFNOSUPPORT);
 
-		RIB_RLOCK(rh);
+		RIB_CFG_RLOCK(rh);
 
 		if (info.rti_info[RTAX_NETMASK] == NULL &&
 		    rtm->rtm_type == RTM_GET) {
@@ -720,7 +723,7 @@ route_output(struct mbuf *m, struct sock
 			    info.rti_info[RTAX_NETMASK], &rh->head);
 
 		if (rt == NULL) {
-			RIB_RUNLOCK(rh);
+			RIB_CFG_RUNLOCK(rh);
 			senderr(ESRCH);
 		}
 #ifdef RADIX_MPATH
@@ -736,7 +739,7 @@ route_output(struct mbuf *m, struct sock
 		    (rtm->rtm_type != RTM_GET || info.rti_info[RTAX_GATEWAY])) {
 			rt = rt_mpath_matchgate(rt, info.rti_info[RTAX_GATEWAY]);
 			if (!rt) {
-				RIB_RUNLOCK(rh);
+				RIB_CFG_RUNLOCK(rh);
 				senderr(ESRCH);
 			}
 		}
@@ -769,13 +772,13 @@ route_output(struct mbuf *m, struct sock
 			 */
 			rt = (struct rtentry *)rh->rnh_matchaddr(&laddr, &rh->head);
 			if (rt == NULL) {
-				RIB_RUNLOCK(rh);
+				RIB_CFG_RUNLOCK(rh);
 				senderr(ESRCH);
 			}
 		} 
 		RT_LOCK(rt);
 		RT_ADDREF(rt);
-		RIB_RUNLOCK(rh);
+		RIB_CFG_RUNLOCK(rh);
 
 report:
 		RT_LOCK_ASSERT(rt);
@@ -1868,10 +1871,10 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
 		for (error = 0; error == 0 && i <= lim; i++) {
 			rh = rt_tables_get_rnh(fib, i);
 			if (rh != NULL) {
-				RIB_RLOCK(rh); 
+				RIB_CFG_RLOCK(rh); 
 			    	error = rh->rnh_walktree(&rh->head,
 				    sysctl_dumpentry, &w);
-				RIB_RUNLOCK(rh);
+				RIB_CFG_RUNLOCK(rh);
 			} else if (af != 0)
 				error = EAFNOSUPPORT;
 		}

Modified: projects/routing/sys/netinet/in_rmx.c
==============================================================================
--- projects/routing/sys/netinet/in_rmx.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/netinet/in_rmx.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/rmlock.h>
 #include <sys/sysctl.h>
 #include <sys/socket.h>
 #include <sys/mbuf.h>
@@ -192,7 +195,7 @@ in_rtqkill(struct rtentry *rt, void *roc
 	struct rtqk_arg *ap = rock;
 	int err;
 
-	RIB_WLOCK_ASSERT(ap->rh);
+	//RIB_WLOCK_ASSERT(ap->rh);
 
 	if (rt->rt_flags & RTPRF_OURS) {
 		ap->found++;
@@ -278,9 +281,11 @@ void
 in_setmatchfunc(struct rib_head *rh, int val)
 {
 
+	RIB_CFG_WLOCK(rh);
 	RIB_WLOCK(rh);
 	rh->rnh_matchaddr = (val != 0) ?  rn_match : in_matroute;
 	RIB_WUNLOCK(rh);
+	RIB_CFG_WUNLOCK(rh);
 }
 
 static int _in_rt_was_here;

Modified: projects/routing/sys/netinet6/nd6_rtr.c
==============================================================================
--- projects/routing/sys/netinet6/nd6_rtr.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/netinet6/nd6_rtr.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/errno.h>
 #include <sys/rwlock.h>
+#include <sys/rmlock.h>
 #include <sys/syslog.h>
 #include <sys/queue.h>
 
@@ -1547,6 +1548,7 @@ nd6_prefix_onlink_rtrequest(struct nd_pr
 
 			rh = rt_tables_get_rnh(rt->rt_fibnum, AF_INET6);
 			/* XXX what if rhn == NULL? */
+			RIB_CFG_WLOCK(rh);
 			RIB_WLOCK(rh);
 			RT_LOCK(rt);
 			if (rt_setgate(rt, rt_key(rt),
@@ -1558,6 +1560,7 @@ nd6_prefix_onlink_rtrequest(struct nd_pr
 				dl->sdl_index = rt->rt_ifp->if_index;
 			}
 			RIB_WUNLOCK(rh);
+			RIB_CFG_WUNLOCK(rh);
 			nd6_rtmsg(RTM_ADD, rt);
 			RT_UNLOCK(rt);
 			pr->ndpr_stateflags |= NDPRF_ONLINK;

Modified: projects/routing/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/routing/sys/netpfil/ipfw/ip_fw_table_algo.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/netpfil/ipfw/ip_fw_table_algo.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -4019,6 +4019,7 @@ ta_foreach_kfib(void *ta_state, struct t
     void *arg)
 {
 	struct rib_head *rh;
+	RIB_LOCK_READER;
 	int error;
 
 	rh = rt_tables_get_rnh(ti->data, AF_INET);

Modified: projects/routing/sys/nfs/bootp_subr.c
==============================================================================
--- projects/routing/sys/nfs/bootp_subr.c	Sun Nov  9 22:59:21 2014	(r274335)
+++ projects/routing/sys/nfs/bootp_subr.c	Mon Nov 10 00:07:06 2014	(r274336)
@@ -375,9 +375,9 @@ bootpboot_p_rtlist(void)
 	rnh = rt_tables_get_rnh(0, AF_INET);
 	if (rnh == NULL)
 		return;
-	RIB_RLOCK(rnh);	/* could sleep XXX */
+	RIB_CFG_RLOCK(rnh);	/* could sleep XXX */
 	bootpboot_p_tree(rh->rnh_treetop);
-	RIB_RUNLOCK(rnh);
+	RIB_CFG_RUNLOCK(rnh);
 }
 
 void



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