mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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 <pabeni@redhat.com> Reviewed-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b9b33e7c24
commit
197dbf24e3
@ -86,11 +86,27 @@ static void ip6_sublist_rcv_finish(struct list_head *head)
|
||||
}
|
||||
}
|
||||
|
||||
static bool ip6_can_use_hint(const struct sk_buff *skb,
|
||||
const struct sk_buff *hint)
|
||||
{
|
||||
return hint && !skb_dst(skb) &&
|
||||
ipv6_addr_equal(&ipv6_hdr(hint)->daddr, &ipv6_hdr(skb)->daddr);
|
||||
}
|
||||
|
||||
static struct sk_buff *ip6_extract_route_hint(const struct net *net,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
if (fib6_routes_require_src(net) || fib6_has_custom_rules(net))
|
||||
return NULL;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct sk_buff *skb, *next, *hint = NULL;
|
||||
struct dst_entry *curr_dst = NULL;
|
||||
struct sk_buff *skb, *next;
|
||||
struct list_head sublist;
|
||||
|
||||
INIT_LIST_HEAD(&sublist);
|
||||
@ -104,9 +120,15 @@ static void ip6_list_rcv_finish(struct net *net, struct sock *sk,
|
||||
skb = l3mdev_ip6_rcv(skb);
|
||||
if (!skb)
|
||||
continue;
|
||||
ip6_rcv_finish_core(net, sk, skb);
|
||||
|
||||
if (ip6_can_use_hint(skb, hint))
|
||||
skb_dst_copy(skb, hint);
|
||||
else
|
||||
ip6_rcv_finish_core(net, sk, skb);
|
||||
dst = skb_dst(skb);
|
||||
if (curr_dst != dst) {
|
||||
hint = ip6_extract_route_hint(net, skb);
|
||||
|
||||
/* dispatch old sublist */
|
||||
if (!list_empty(&sublist))
|
||||
ip6_sublist_rcv_finish(&sublist);
|
||||
|
Loading…
Reference in New Issue
Block a user