Date: Sun, 21 Jun 2009 19:30:33 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r194602 - in head/sys: net netatalk netinet netinet6 netipx Message-ID: <200906211930.n5LJUXVJ016236@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rwatson Date: Sun Jun 21 19:30:33 2009 New Revision: 194602 URL: http://svn.freebsd.org/changeset/base/194602 Log: Clean up common ifaddr management: - Unify reference count and lock initialization in a single function, ifa_init(). - Move tear-down from a macro (IFAFREE) to a function ifa_free(). - Move reference count bump from a macro (IFAREF) to a function ifa_ref(). - Instead of using a u_int protected by a mutex to refcount(9) for reference count management. The ifa_mtx is now used for exactly one ioctl, and possibly should be removed. MFC after: 3 weeks Modified: head/sys/net/if.c head/sys/net/if_var.h head/sys/net/route.c head/sys/net/rtsock.c head/sys/netatalk/at_control.c head/sys/netinet/in.c head/sys/netinet6/in6.c head/sys/netinet6/in6_ifattach.c head/sys/netinet6/nd6_nbr.c head/sys/netipx/ipx.c Modified: head/sys/net/if.c ============================================================================== --- head/sys/net/if.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/net/if.c Sun Jun 21 19:30:33 2009 (r194602) @@ -758,7 +758,7 @@ if_attach_internal(struct ifnet *ifp, in socksize = roundup2(socksize, sizeof(long)); ifasize = sizeof(*ifa) + 2 * socksize; ifa = malloc(ifasize, M_IFADDR, M_WAITOK | M_ZERO); - IFA_LOCK_INIT(ifa); + ifa_init(ifa); sdl = (struct sockaddr_dl *)(ifa + 1); sdl->sdl_len = socksize; sdl->sdl_family = AF_LINK; @@ -775,7 +775,6 @@ if_attach_internal(struct ifnet *ifp, in sdl->sdl_len = masklen; while (namelen != 0) sdl->sdl_data[--namelen] = 0xff; - ifa->ifa_refcnt = 1; TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); /* Reliably crash if used uninitialized. */ ifp->if_broadcastaddr = NULL; @@ -896,7 +895,7 @@ if_purgeaddrs(struct ifnet *ifp) } #endif /* INET6 */ TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); - IFAFREE(ifa); + ifa_free(ifa); } } @@ -1013,7 +1012,7 @@ if_detach_internal(struct ifnet *ifp, in if (!TAILQ_EMPTY(&ifp->if_addrhead)) { ifa = TAILQ_FIRST(&ifp->if_addrhead); TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); - IFAFREE(ifa); + ifa_free(ifa); } } @@ -1420,6 +1419,34 @@ if_rtdel(struct radix_node *rn, void *ar } /* + * Reference count functions for ifaddrs. + */ +void +ifa_init(struct ifaddr *ifa) +{ + + mtx_init(&ifa->ifa_mtx, "ifaddr", NULL, MTX_DEF); + refcount_init(&ifa->ifa_refcnt, 1); +} + +void +ifa_ref(struct ifaddr *ifa) +{ + + refcount_acquire(&ifa->ifa_refcnt); +} + +void +ifa_free(struct ifaddr *ifa) +{ + + if (refcount_release(&ifa->ifa_refcnt)) { + mtx_destroy(&ifa->ifa_mtx); + free(ifa, M_IFADDR); + } +} + +/* * XXX: Because sockaddr_dl has deeper structure than the sockaddr * structs used to represent other address families, it is necessary * to perform a different comparison. @@ -1711,10 +1738,10 @@ link_rtrequest(int cmd, struct rtentry * return; ifa = ifaof_ifpforaddr(dst, ifp); if (ifa) { - IFAREF(ifa); /* XXX */ + ifa_ref(ifa); /* XXX */ oifa = rt->rt_ifa; rt->rt_ifa = ifa; - IFAFREE(oifa); + ifa_free(oifa); if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) ifa->ifa_rtrequest(cmd, rt, info); } Modified: head/sys/net/if_var.h ============================================================================== --- head/sys/net/if_var.h Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/net/if_var.h Sun Jun 21 19:30:33 2009 (r194602) @@ -706,11 +706,14 @@ struct ifaddr { /* for compatibility with other BSDs */ #define ifa_list ifa_link -#define IFA_LOCK_INIT(ifa) \ - mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) +#ifdef _KERNEL #define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) #define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) -#define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) + +void ifa_free(struct ifaddr *ifa); +void ifa_init(struct ifaddr *ifa); +void ifa_ref(struct ifaddr *ifa); +#endif /* * The prefix structure contains information about one prefix @@ -741,24 +744,6 @@ struct ifmultiaddr { }; #ifdef _KERNEL -#define IFAFREE(ifa) \ - do { \ - IFA_LOCK(ifa); \ - KASSERT((ifa)->ifa_refcnt > 0, \ - ("ifa %p !(ifa_refcnt > 0)", ifa)); \ - if (--(ifa)->ifa_refcnt == 0) { \ - IFA_DESTROY(ifa); \ - free(ifa, M_IFADDR); \ - } else \ - IFA_UNLOCK(ifa); \ - } while (0) - -#define IFAREF(ifa) \ - do { \ - IFA_LOCK(ifa); \ - ++(ifa)->ifa_refcnt; \ - IFA_UNLOCK(ifa); \ - } while (0) extern struct rwlock ifnet_lock; #define IFNET_LOCK_INIT() \ Modified: head/sys/net/route.c ============================================================================== --- head/sys/net/route.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/net/route.c Sun Jun 21 19:30:33 2009 (r194602) @@ -474,7 +474,7 @@ rtfree(struct rtentry *rt) * e.g other routes and ifaddrs. */ if (rt->rt_ifa) - IFAFREE(rt->rt_ifa); + ifa_free(rt->rt_ifa); /* * The key is separatly alloc'd so free it (see rt_setgate()). * This also frees the gateway, as they are always malloc'd @@ -1126,7 +1126,7 @@ rtrequest1_fib(int req, struct rt_addrin * This moved from below so that rnh->rnh_addaddr() can * examine the ifa and ifa->ifa_ifp if it so desires. */ - IFAREF(ifa); + ifa_ref(ifa); rt->rt_ifa = ifa; rt->rt_ifp = ifa->ifa_ifp; rt->rt_rmx.rmx_weight = 1; @@ -1136,7 +1136,7 @@ rtrequest1_fib(int req, struct rt_addrin if (rn_mpath_capable(rnh) && rt_mpath_conflict(rnh, rt, netmask)) { if (rt->rt_ifa) { - IFAFREE(rt->rt_ifa); + ifa_free(rt->rt_ifa); } Free(rt_key(rt)); RT_LOCK_DESTROY(rt); @@ -1153,7 +1153,7 @@ rtrequest1_fib(int req, struct rt_addrin */ if (rn == NULL) { if (rt->rt_ifa) - IFAFREE(rt->rt_ifa); + ifa_free(rt->rt_ifa); Free(rt_key(rt)); RT_LOCK_DESTROY(rt); uma_zfree(V_rtzone, rt); @@ -1409,8 +1409,8 @@ rtinit1(struct ifaddr *ifa, int cmd, int */ if (memcmp(rt->rt_ifa->ifa_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len)) { - IFAFREE(rt->rt_ifa); - IFAREF(ifa); + ifa_free(rt->rt_ifa); + ifa_ref(ifa); rt->rt_ifp = ifa->ifa_ifp; rt->rt_ifa = ifa; } Modified: head/sys/net/rtsock.c ============================================================================== --- head/sys/net/rtsock.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/net/rtsock.c Sun Jun 21 19:30:33 2009 (r194602) @@ -694,7 +694,7 @@ route_output(struct mbuf *m, struct sock rt->rt_ifa->ifa_rtrequest != NULL) { rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, &info); - IFAFREE(rt->rt_ifa); + ifa_free(rt->rt_ifa); } if (info.rti_info[RTAX_GATEWAY] != NULL) { RT_UNLOCK(rt); @@ -712,7 +712,7 @@ route_output(struct mbuf *m, struct sock } if (info.rti_ifa != NULL && info.rti_ifa != rt->rt_ifa) { - IFAREF(info.rti_ifa); + ifa_ref(info.rti_ifa); rt->rt_ifa = info.rti_ifa; rt->rt_ifp = info.rti_ifp; } Modified: head/sys/netatalk/at_control.c ============================================================================== --- head/sys/netatalk/at_control.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/netatalk/at_control.c Sun Jun 21 19:30:33 2009 (r194602) @@ -189,8 +189,7 @@ at_control(struct socket *so, u_long cmd * and link our new one on the end */ ifa = (struct ifaddr *)aa; - IFA_LOCK_INIT(ifa); - ifa->ifa_refcnt = 1; + ifa_init(ifa); /* * As the at_ifaddr contains the actual sockaddrs, @@ -325,7 +324,7 @@ at_control(struct socket *so, u_long cmd /* * Now reclaim the reference. */ - IFAFREE(ifa0); + ifa_free(ifa0); break; default: Modified: head/sys/netinet/in.c ============================================================================== --- head/sys/netinet/in.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/netinet/in.c Sun Jun 21 19:30:33 2009 (r194602) @@ -377,11 +377,10 @@ in_control(struct socket *so, u_long cmd } ifa = &ia->ia_ifa; - IFA_LOCK_INIT(ifa); + ifa_init(ifa); ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask; - ifa->ifa_refcnt = 1; ia->ia_sockmask.sin_len = 8; ia->ia_sockmask.sin_family = AF_INET; @@ -617,7 +616,7 @@ in_control(struct socket *so, u_long cmd IN_MULTI_UNLOCK(); } } - IFAFREE(&ia->ia_ifa); + ifa_free(&ia->ia_ifa); splx(s); return (error); Modified: head/sys/netinet6/in6.c ============================================================================== --- head/sys/netinet6/in6.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/netinet6/in6.c Sun Jun 21 19:30:33 2009 (r194602) @@ -784,9 +784,9 @@ in6_update_ifa(struct ifnet *ifp, struct if (ia == NULL) return (ENOBUFS); bzero((caddr_t)ia, sizeof(*ia)); + ifa_init(&ia->ia_ifa); LIST_INIT(&ia->ia6_memberships); /* Initialize the address and masks, and put time stamp */ - IFA_LOCK_INIT(&ia->ia_ifa); ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ia->ia_addr.sin6_family = AF_INET6; ia->ia_addr.sin6_len = sizeof(ia->ia_addr); @@ -811,7 +811,6 @@ in6_update_ifa(struct ifnet *ifp, struct } else V_in6_ifaddr = ia; - ia->ia_ifa.ifa_refcnt = 1; IF_ADDR_LOCK(ifp); TAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); IF_ADDR_UNLOCK(ifp); @@ -1387,7 +1386,7 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st * release another refcnt for the link from in6_ifaddr. * Note that we should decrement the refcnt at least once for all *BSD. */ - IFAFREE(&oia->ia_ifa); + ifa_free(&oia->ia_ifa); splx(s); } Modified: head/sys/netinet6/in6_ifattach.c ============================================================================== --- head/sys/netinet6/in6_ifattach.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/netinet6/in6_ifattach.c Sun Jun 21 19:30:33 2009 (r194602) @@ -827,7 +827,7 @@ in6_ifdetach(struct ifnet *ifp) IF_ADDR_LOCK(ifp); TAILQ_REMOVE(&ifp->if_addrhead, (struct ifaddr *)ia, ifa_link); IF_ADDR_UNLOCK(ifp); - IFAFREE(&ia->ia_ifa); + ifa_free(&ia->ia_ifa); /* also remove from the IPv6 address chain(itojun&jinmei) */ oia = ia; @@ -845,7 +845,7 @@ in6_ifdetach(struct ifnet *ifp) } } - IFAFREE(&oia->ia_ifa); + ifa_free(&oia->ia_ifa); } in6_pcbpurgeif0(&V_udbinfo, ifp); Modified: head/sys/netinet6/nd6_nbr.c ============================================================================== --- head/sys/netinet6/nd6_nbr.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/netinet6/nd6_nbr.c Sun Jun 21 19:30:33 2009 (r194602) @@ -1223,7 +1223,7 @@ nd6_dad_start(struct ifaddr *ifa, int de * (re)initialization. */ dp->dad_ifa = ifa; - IFAREF(ifa); /* just for safety */ + ifa_ref(ifa); /* just for safety */ dp->dad_count = V_ip6_dad_count; dp->dad_ns_icount = dp->dad_na_icount = 0; dp->dad_ns_ocount = dp->dad_ns_tcount = 0; @@ -1258,7 +1258,7 @@ nd6_dad_stop(struct ifaddr *ifa) TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); free(dp, M_IP6NDP); dp = NULL; - IFAFREE(ifa); + ifa_free(ifa); } static void @@ -1301,7 +1301,7 @@ nd6_dad_timer(struct dadq *dp) TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); free(dp, M_IP6NDP); dp = NULL; - IFAFREE(ifa); + ifa_free(ifa); goto done; } @@ -1354,7 +1354,7 @@ nd6_dad_timer(struct dadq *dp) TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); free(dp, M_IP6NDP); dp = NULL; - IFAFREE(ifa); + ifa_free(ifa); } } @@ -1432,7 +1432,7 @@ nd6_dad_duplicated(struct ifaddr *ifa) TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); free(dp, M_IP6NDP); dp = NULL; - IFAFREE(ifa); + ifa_free(ifa); } static void Modified: head/sys/netipx/ipx.c ============================================================================== --- head/sys/netipx/ipx.c Sun Jun 21 19:21:01 2009 (r194601) +++ head/sys/netipx/ipx.c Sun Jun 21 19:30:33 2009 (r194602) @@ -170,8 +170,7 @@ ipx_control(struct socket *so, u_long cm ipx_ifaddr = oia; ia = oia; ifa = (struct ifaddr *)ia; - IFA_LOCK_INIT(ifa); - ifa->ifa_refcnt = 1; + ifa_init(ifa); TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); ia->ia_ifp = ifp; ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; @@ -231,7 +230,7 @@ ipx_control(struct socket *so, u_long cm else printf("Didn't unlink ipxifadr from list\n"); } - IFAFREE((&oia->ia_ifa)); + ifa_free(&oia->ia_ifa); return (0); case SIOCAIFADDR:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906211930.n5LJUXVJ016236>