diff options
author | ae <ae@FreeBSD.org> | 2015-07-29 08:12:05 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2015-07-29 08:12:05 +0000 |
commit | 75425458ac884224851416fa8b7b06d187702f59 (patch) | |
tree | 138dc350c71d58f402cf101b1018071f60b0ab4b /sys/netinet/in_mcast.c | |
parent | 5583964cfc80625a7658e4e03e934d60792eff3b (diff) | |
download | FreeBSD-src-75425458ac884224851416fa8b7b06d187702f59.zip FreeBSD-src-75425458ac884224851416fa8b7b06d187702f59.tar.gz |
Convert in_ifaddr_lock and in6_ifaddr_lock to rmlock.
Both are used to protect access to IP addresses lists and they can be
acquired for reading several times per packet. To reduce lock contention
it is better to use rmlock here.
Reviewed by: gnn (previous version)
Obtained from: Yandex LLC
Sponsored by: Yandex LLC
Differential Revision: https://reviews.freebsd.org/D3149
Diffstat (limited to 'sys/netinet/in_mcast.c')
-rw-r--r-- | sys/netinet/in_mcast.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c index 93557f8..c168780 100644 --- a/sys/netinet/in_mcast.c +++ b/sys/netinet/in_mcast.c @@ -38,9 +38,11 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/protosw.h> +#include <sys/rmlock.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/protosw.h> @@ -1748,6 +1750,7 @@ inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt) int inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) { + struct rm_priotracker in_ifa_tracker; struct ip_mreqn mreqn; struct ip_moptions *imo; struct ifnet *ifp; @@ -1787,7 +1790,7 @@ inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) mreqn.imr_address = imo->imo_multicast_addr; } else if (ifp != NULL) { mreqn.imr_ifindex = ifp->if_index; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { mreqn.imr_address = IA_SIN(ia)->sin_addr; @@ -1878,6 +1881,7 @@ static struct ifnet * inp_lookup_mcast_ifp(const struct inpcb *inp, const struct sockaddr_in *gsin, const struct in_addr ina) { + struct rm_priotracker in_ifa_tracker; struct ifnet *ifp; KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__)); @@ -1902,7 +1906,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, struct ifnet *mifp; mifp = NULL; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { mifp = ia->ia_ifp; if (!(mifp->if_flags & IFF_LOOPBACK) && @@ -1911,7 +1915,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, break; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } |