Re: [PATCH net-next] net: Optimize IPv6 path in ip_neigh_for_gw()

From: Paolo Abeni
Date: Tue Oct 08 2024 - 06:51:18 EST


On 10/4/24 19:37, Breno Leitao wrote:
On Fri, Oct 04, 2024 at 11:01:29AM -0600, David Ahern wrote:
On 10/4/24 10:27 AM, Breno Leitao wrote:
Branch annotation traces from approximately 200 IPv6-enabled hosts
revealed that the 'likely' branch in ip_neigh_for_gw() was consistently
mispredicted. Given the increasing prevalence of IPv6 in modern networks,
this commit adjusts the function to favor the IPv6 path.

Swap the order of the conditional statements and move the 'likely'
annotation to the IPv6 case. This change aims to improve performance in
IPv6-dominant environments by reducing branch mispredictions.

This optimization aligns with the trend of IPv6 becoming the default IP
version in many deployments, and should benefit modern network
configurations.

Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
include/net/route.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/net/route.h b/include/net/route.h
index 1789f1e6640b..b90b7b1effb8 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -389,11 +389,11 @@ static inline struct neighbour *ip_neigh_for_gw(struct rtable *rt,
struct net_device *dev = rt->dst.dev;
struct neighbour *neigh;
- if (likely(rt->rt_gw_family == AF_INET)) {
- neigh = ip_neigh_gw4(dev, rt->rt_gw4);
- } else if (rt->rt_gw_family == AF_INET6) {
+ if (likely(rt->rt_gw_family == AF_INET6)) {
neigh = ip_neigh_gw6(dev, &rt->rt_gw6);
*is_v6gw = true;
+ } else if (rt->rt_gw_family == AF_INET) {
+ neigh = ip_neigh_gw4(dev, rt->rt_gw4);
} else {
neigh = ip_neigh_gw4(dev, ip_hdr(skb)->daddr);
}

This is an IPv4 function allowing support for IPv6 addresses as a
nexthop. It is appropriate for IPv4 family checks to be first.

Right. In which case is this called on IPv6 only systems?

On my IPv6-only 200 systems, the annotated branch predictor is showing
it is mispredicted 100% of the time.

perf probe -a ip_neigh_for_gw; perf record -e probe:ip_neigh_for_gw -ag; perf script

should give you an hint.

Cheers,

Paolo