Do not reference returned ifa in in6_ifawithifp().
The only place where in6_ifawithifp() is used is ip6_output(), which uses the returned ifa to bump traffic counters. Given ifa stability guarantees is provided by epoch, do not refcount ifa. This eliminates 2 atomic ops from IPv6 fast path. Reviewed By: rstone MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D28649
This commit is contained in:
parent
25c6318c79
commit
1bd44b11e5
@ -1921,10 +1921,8 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
|
||||
besta = (struct in6_ifaddr *)ifa;
|
||||
}
|
||||
}
|
||||
if (besta) {
|
||||
ifa_ref(&besta->ia_ifa);
|
||||
if (besta)
|
||||
return (besta);
|
||||
}
|
||||
|
||||
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6)
|
||||
@ -1941,20 +1939,14 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ifa != NULL)
|
||||
ifa_ref(ifa);
|
||||
return (struct in6_ifaddr *)ifa;
|
||||
}
|
||||
|
||||
/* use the last-resort values, that are, deprecated addresses */
|
||||
if (dep[0]) {
|
||||
ifa_ref((struct ifaddr *)dep[0]);
|
||||
if (dep[0])
|
||||
return dep[0];
|
||||
}
|
||||
if (dep[1]) {
|
||||
ifa_ref((struct ifaddr *)dep[1]);
|
||||
if (dep[1])
|
||||
return dep[1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1177,7 +1177,6 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
counter_u64_add(ia6->ia_ifa.ifa_opackets, 1);
|
||||
counter_u64_add(ia6->ia_ifa.ifa_obytes,
|
||||
m->m_pkthdr.len);
|
||||
ifa_free(&ia6->ia_ifa);
|
||||
}
|
||||
error = ip6_output_send(inp, ifp, origifp, m, dst, ro,
|
||||
(flags & IP_NO_SND_TAG_RL) ? false : true);
|
||||
|
Loading…
Reference in New Issue
Block a user