]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.34/ipv6-sr-fix-seg6-encap-performances-with-tso-enabled.patch
Linux 4.14.95
[thirdparty/kernel/stable-queue.git] / releases / 4.14.34 / ipv6-sr-fix-seg6-encap-performances-with-tso-enabled.patch
1 From foo@baz Tue Apr 10 23:20:08 CEST 2018
2 From: David Lebrun <dlebrun@google.com>
3 Date: Thu, 29 Mar 2018 17:59:36 +0100
4 Subject: ipv6: sr: fix seg6 encap performances with TSO enabled
5
6 From: David Lebrun <dlebrun@google.com>
7
8
9 [ Upstream commit 5807b22c9164a21cd1077a9bc587f0bba361f72d ]
10
11 Enabling TSO can lead to abysmal performances when using seg6 in
12 encap mode, such as with the ixgbe driver. This patch adds a call to
13 iptunnel_handle_offloads() to remove the encapsulation bit if needed.
14
15 Before:
16 root@comp4-seg6bpf:~# iperf3 -c fc00::55
17 Connecting to host fc00::55, port 5201
18 [ 4] local fc45::4 port 36592 connected to fc00::55 port 5201
19 [ ID] Interval Transfer Bandwidth Retr Cwnd
20 [ 4] 0.00-1.00 sec 196 KBytes 1.60 Mbits/sec 47 6.66 KBytes
21 [ 4] 1.00-2.00 sec 304 KBytes 2.49 Mbits/sec 100 5.33 KBytes
22 [ 4] 2.00-3.00 sec 284 KBytes 2.32 Mbits/sec 92 5.33 KBytes
23
24 After:
25 root@comp4-seg6bpf:~# iperf3 -c fc00::55
26 Connecting to host fc00::55, port 5201
27 [ 4] local fc45::4 port 43062 connected to fc00::55 port 5201
28 [ ID] Interval Transfer Bandwidth Retr Cwnd
29 [ 4] 0.00-1.00 sec 1.03 GBytes 8.89 Gbits/sec 0 743 KBytes
30 [ 4] 1.00-2.00 sec 1.03 GBytes 8.87 Gbits/sec 0 743 KBytes
31 [ 4] 2.00-3.00 sec 1.03 GBytes 8.87 Gbits/sec 0 743 KBytes
32
33 Reported-by: Tom Herbert <tom@quantonium.net>
34 Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels")
35 Signed-off-by: David Lebrun <dlebrun@google.com>
36 Signed-off-by: David S. Miller <davem@davemloft.net>
37 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38 ---
39 net/ipv6/seg6_iptunnel.c | 16 +++++++---------
40 1 file changed, 7 insertions(+), 9 deletions(-)
41
42 --- a/net/ipv6/seg6_iptunnel.c
43 +++ b/net/ipv6/seg6_iptunnel.c
44 @@ -16,6 +16,7 @@
45 #include <linux/net.h>
46 #include <linux/module.h>
47 #include <net/ip.h>
48 +#include <net/ip_tunnels.h>
49 #include <net/lwtunnel.h>
50 #include <net/netevent.h>
51 #include <net/netns/generic.h>
52 @@ -211,11 +212,6 @@ static int seg6_do_srh(struct sk_buff *s
53
54 tinfo = seg6_encap_lwtunnel(dst->lwtstate);
55
56 - if (likely(!skb->encapsulation)) {
57 - skb_reset_inner_headers(skb);
58 - skb->encapsulation = 1;
59 - }
60 -
61 switch (tinfo->mode) {
62 case SEG6_IPTUN_MODE_INLINE:
63 if (skb->protocol != htons(ETH_P_IPV6))
64 @@ -224,10 +220,12 @@ static int seg6_do_srh(struct sk_buff *s
65 err = seg6_do_srh_inline(skb, tinfo->srh);
66 if (err)
67 return err;
68 -
69 - skb_reset_inner_headers(skb);
70 break;
71 case SEG6_IPTUN_MODE_ENCAP:
72 + err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6);
73 + if (err)
74 + return err;
75 +
76 if (skb->protocol == htons(ETH_P_IPV6))
77 proto = IPPROTO_IPV6;
78 else if (skb->protocol == htons(ETH_P_IP))
79 @@ -239,6 +237,8 @@ static int seg6_do_srh(struct sk_buff *s
80 if (err)
81 return err;
82
83 + skb_set_inner_transport_header(skb, skb_transport_offset(skb));
84 + skb_set_inner_protocol(skb, skb->protocol);
85 skb->protocol = htons(ETH_P_IPV6);
86 break;
87 case SEG6_IPTUN_MODE_L2ENCAP:
88 @@ -262,8 +262,6 @@ static int seg6_do_srh(struct sk_buff *s
89 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
90 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
91
92 - skb_set_inner_protocol(skb, skb->protocol);
93 -
94 return 0;
95 }
96