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/if_ether.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/if_ether.c')
-rw-r--r-- | sys/netinet/if_ether.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index aa370d6..1012e93 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -42,12 +42,14 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/queue.h> #include <sys/sysctl.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/rmlock.h> #include <sys/socket.h> #include <sys/syslog.h> @@ -563,6 +565,7 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_log_per_second, static void in_arpinput(struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct arphdr *ah; struct ifnet *ifp = m->m_pkthdr.rcvif; struct llentry *la = NULL; @@ -621,7 +624,7 @@ in_arpinput(struct mbuf *m) * of the receive interface. (This will change slightly * when we have clusters of interfaces). */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || ia->ia_ifp == ifp) && @@ -629,7 +632,7 @@ in_arpinput(struct mbuf *m) (ia->ia_ifa.ifa_carp == NULL || (*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } @@ -638,7 +641,7 @@ in_arpinput(struct mbuf *m) ia->ia_ifp == ifp) && isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } @@ -657,13 +660,13 @@ in_arpinput(struct mbuf *m) if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia)) { ifa_ref(&ia->ia_ifa); ifp = ia->ia_ifp; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } } #undef BDG_MEMBER_MATCHES_ARP - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * No match, use the first inet address on the receive interface @@ -684,13 +687,13 @@ in_arpinput(struct mbuf *m) /* * If bridging, fall back to using any inet address. */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); if (!bridged || (ia = TAILQ_FIRST(&V_in_ifaddrhead)) == NULL) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto drop; } ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); match: if (!enaddr) enaddr = (u_int8_t *)IF_LLADDR(ifp); |