diff options
author | Matt Macy <mmacy@FreeBSD.org> | 2018-05-23 21:02:14 +0000 |
---|---|---|
committer | Matt Macy <mmacy@FreeBSD.org> | 2018-05-23 21:02:14 +0000 |
commit | 4f6c66cc9c75c857341b6ca6ca92d4808be8d3b5 (patch) | |
tree | 4bfcf94f0a6ca1b0584e050e141fcc97051aad44 /sys/netinet6/raw_ip6.c | |
parent | 630ba2c514d723e8c55b5a513b541b614338047f (diff) |
UDP: further performance improvements on tx
Cumulative throughput while running 64
netperf -H $DUT -t UDP_STREAM -- -m 1
on a 2x8x2 SKL went from 1.1Mpps to 2.5Mpps
Single stream throughput increases from 910kpps to 1.18Mpps
Baseline:
https://people.freebsd.org/~mmacy/2018.05.11/udpsender2.svg
- Protect read access to global ifnet list with epoch
https://people.freebsd.org/~mmacy/2018.05.11/udpsender3.svg
- Protect short lived ifaddr references with epoch
https://people.freebsd.org/~mmacy/2018.05.11/udpsender4.svg
- Convert if_afdata read lock path to epoch
https://people.freebsd.org/~mmacy/2018.05.11/udpsender5.svg
A fix for the inpcbhash contention is pending sufficient time
on a canary at LLNW.
Reviewed by: gallatin
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D15409
Notes
Notes:
svn path=/head/; revision=334118
Diffstat (limited to 'sys/netinet6/raw_ip6.c')
-rw-r--r-- | sys/netinet6/raw_ip6.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index b8de413593d6..a6811c68c2f4 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -734,23 +734,25 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td) return (EINVAL); if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0) return (error); - if (TAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6) + if (CK_STAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6) return (EADDRNOTAVAIL); if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0) return (error); + NET_EPOCH_ENTER(); if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && - (ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) + (ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) { + NET_EPOCH_EXIT(); return (EADDRNOTAVAIL); + } if (ifa != NULL && ((struct in6_ifaddr *)ifa)->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY| IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) { - ifa_free(ifa); + NET_EPOCH_EXIT(); return (EADDRNOTAVAIL); } - if (ifa != NULL) - ifa_free(ifa); + NET_EPOCH_EXIT(); INP_INFO_WLOCK(&V_ripcbinfo); INP_WLOCK(inp); inp->in6p_laddr = addr->sin6_addr; @@ -772,7 +774,7 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td) if (nam->sa_len != sizeof(*addr)) return (EINVAL); - if (TAILQ_EMPTY(&V_ifnet)) + if (CK_STAILQ_EMPTY(&V_ifnet)) return (EADDRNOTAVAIL); if (addr->sin6_family != AF_INET6) return (EAFNOSUPPORT); |