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>