Skip to content

Commit 197dbf2

Browse files
Paolo Abenidavem330
authored andcommitted
ipv6: introduce and uses route look hints for list input.
When doing RX batch packet processing, we currently always repeat the route lookup for each ingress packet. When no custom rules are in place, and there aren't routes depending on source addresses, we know that packets with the same destination address will use the same dst. This change tries to avoid per packet route lookup caching the destination address of the latest successful lookup, and reusing it for the next packet when the above conditions are in place. Ingress traffic for most servers should fit. The measured performance delta under UDP flood vs a recvmmsg receiver is as follow: vanilla patched delta Kpps Kpps % 1431 1674 +17 In the worst-case scenario - each packet has a different destination address - the performance delta is within noise range. v3 -> v4: - support hints for SUBFLOW build, too (David A.) - several style fixes (Eric) v2 -> v3: - add fib6_has_custom_rules() helpers (David A.) - add ip6_extract_route_hint() helper (Edward C.) - use hint directly in ip6_list_rcv_finish() (Willem) v1 -> v2: - fix build issue with !CONFIG_IPV6_MULTIPLE_TABLES - fix potential race when fib6_has_custom_rules is set while processing a packet batch Signed-off-by: Paolo Abeni <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b9b33e7 commit 197dbf2

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

net/ipv6/ip6_input.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,27 @@ static void ip6_sublist_rcv_finish(struct list_head *head)
8686
}
8787
}
8888

89+
static bool ip6_can_use_hint(const struct sk_buff *skb,
90+
const struct sk_buff *hint)
91+
{
92+
return hint && !skb_dst(skb) &&
93+
ipv6_addr_equal(&ipv6_hdr(hint)->daddr, &ipv6_hdr(skb)->daddr);
94+
}
95+
96+
static struct sk_buff *ip6_extract_route_hint(const struct net *net,
97+
struct sk_buff *skb)
98+
{
99+
if (fib6_routes_require_src(net) || fib6_has_custom_rules(net))
100+
return NULL;
101+
102+
return skb;
103+
}
104+
89105
static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
90106
struct list_head *head)
91107
{
108+
struct sk_buff *skb, *next, *hint = NULL;
92109
struct dst_entry *curr_dst = NULL;
93-
struct sk_buff *skb, *next;
94110
struct list_head sublist;
95111

96112
INIT_LIST_HEAD(&sublist);
@@ -104,9 +120,15 @@ static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
104120
skb = l3mdev_ip6_rcv(skb);
105121
if (!skb)
106122
continue;
107-
ip6_rcv_finish_core(net, sk, skb);
123+
124+
if (ip6_can_use_hint(skb, hint))
125+
skb_dst_copy(skb, hint);
126+
else
127+
ip6_rcv_finish_core(net, sk, skb);
108128
dst = skb_dst(skb);
109129
if (curr_dst != dst) {
130+
hint = ip6_extract_route_hint(net, skb);
131+
110132
/* dispatch old sublist */
111133
if (!list_empty(&sublist))
112134
ip6_sublist_rcv_finish(&sublist);

0 commit comments

Comments
 (0)