From: Tom Herbert <hidden> Date: 2014-09-09 18:23:34
This patch sets populates the IPIP and SIT offload structures with
gro_receive and gro_complete functions. This enables use of GRO
for these. Also, fixed a problem in IPv6 where we were not properly
initializing flush_id.
Peformance results are below. Note that these tests were done on bnx2x
which doesn't provide RX checksum offload of IPIP or SIT (i.e. does
not give CHEKCSUM_COMPLETE). Also, we don't get 4-tuple hash for RSS
only 2-tuple in this case so all the packets between two hosts are
winding up on the same queue. Net result is the interrupting CPU is
the bottleneck in GRO (checksumming every packet there).
Testing:
netperf TCP_STREAM between two hosts using bnx2x.
* Before fix
IPIP
1 connection
6.53% CPU utilization
6544.71 Mbps
20 connections
13.79% CPU utilization
9284.54 Mbps
SIT
1 connection
6.68% CPU utilization
5653.36 Mbps
20 connections
18.88% CPU utilization
9154.61 Mbps
* After fix
IPIP
1 connection
5.73% CPU utilization
9279.53 Mbps
20 connections
7.14% CPU utilization
7279.35 Mbps
SIT
1 connection
2.95% CPU utilization
9143.36 Mbps
20 connections
7.09% CPU utilization
6255.3 Mbps
Tom Herbert (3):
ipv6: Clear flush_id to make GRO work
ipip: Add gro callbacks to ipip offload
sit: Add gro callbacks to sit_offload
net/ipv4/af_inet.c | 2 ++
net/ipv6/ip6_offload.c | 5 +++++
2 files changed, 7 insertions(+)
--
2.1.0.rc2.206.gedb03e5
From: Tom Herbert <hidden> Date: 2014-09-09 18:23:44
In TCP gro we check flush_id which is derived from the IP identifier.
In IPv4 gro path the flush_id is set with the expectation that every
matched packet increments IP identifier. In IPv6, the flush_id is
never set and thus is uinitialized. What's worse is that in IPv6
over IPv4 encapsulation, the IP identifier is taken from the outer
header which is currently not incremented on every packet for Linux
stack, so GRO in this case never matches packets (identifier is
not increasing).
This patch clears flush_id for every time for a matched packet in
IPv6 gro_receive. We need to do this each time to overwrite the
setting that would be done in IPv4 gro_receive per the outer
header in IPv6 over Ipv4 encapsulation.
Signed-off-by: Tom Herbert <redacted>
---
net/ipv6/ip6_offload.c | 3 +++
1 file changed, 3 insertions(+)
@@ -261,6 +261,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,/* flush if Traffic Class fields are different */NAPI_GRO_CB(p)->flush|=!!(first_word&htonl(0x0FF00000));NAPI_GRO_CB(p)->flush|=flush;++/* Clear flush_id, there's really no concept of ID in IPv6. */+NAPI_GRO_CB(p)->flush_id=0;}NAPI_GRO_CB(skb)->flush|=flush;
From: Tom Herbert <hidden> Date: 2014-09-09 18:23:50
Add inet_gro_receive and inet_gro_complete to ipip_offload to
support GRO.
Signed-off-by: Tom Herbert <redacted>
---
net/ipv4/af_inet.c | 2 ++
1 file changed, 2 insertions(+)
From: Tom Herbert <hidden> Date: 2014-09-09 18:23:57
Add ipv6_gro_receive and ipv6_gro_complete to sit_offload to
support GRO.
Signed-off-by: Tom Herbert <redacted>
---
net/ipv6/ip6_offload.c | 2 ++
1 file changed, 2 insertions(+)
From: Eric Dumazet <hidden> Date: 2014-09-09 18:38:08
On Tue, 2014-09-09 at 11:23 -0700, Tom Herbert wrote:
quoted hunk
In TCP gro we check flush_id which is derived from the IP identifier.
In IPv4 gro path the flush_id is set with the expectation that every
matched packet increments IP identifier. In IPv6, the flush_id is
never set and thus is uinitialized. What's worse is that in IPv6
over IPv4 encapsulation, the IP identifier is taken from the outer
header which is currently not incremented on every packet for Linux
stack, so GRO in this case never matches packets (identifier is
not increasing).
This patch clears flush_id for every time for a matched packet in
IPv6 gro_receive. We need to do this each time to overwrite the
setting that would be done in IPv4 gro_receive per the outer
header in IPv6 over Ipv4 encapsulation.
Signed-off-by: Tom Herbert <redacted>
---
net/ipv6/ip6_offload.c | 3 +++
1 file changed, 3 insertions(+)
@@ -261,6 +261,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,/* flush if Traffic Class fields are different */NAPI_GRO_CB(p)->flush|=!!(first_word&htonl(0x0FF00000));NAPI_GRO_CB(p)->flush|=flush;++/* Clear flush_id, there's really no concept of ID in IPv6. */+NAPI_GRO_CB(p)->flush_id=0;}NAPI_GRO_CB(skb)->flush|=flush;
Yeah, I mentioned this problem months ago and apparently forgot to push
the fix.
http://patchwork.ozlabs.org/patch/311212/
Signed-off-by: Eric Dumazet <edumazet@google.com>
From: Tom Herbert <hidden> Date: 2014-09-09 18:52:16
On Tue, Sep 9, 2014 at 11:38 AM, Eric Dumazet [off-list ref] wrote:
On Tue, 2014-09-09 at 11:23 -0700, Tom Herbert wrote:
quoted
In TCP gro we check flush_id which is derived from the IP identifier.
In IPv4 gro path the flush_id is set with the expectation that every
matched packet increments IP identifier. In IPv6, the flush_id is
never set and thus is uinitialized. What's worse is that in IPv6
over IPv4 encapsulation, the IP identifier is taken from the outer
header which is currently not incremented on every packet for Linux
stack, so GRO in this case never matches packets (identifier is
not increasing).
This patch clears flush_id for every time for a matched packet in
IPv6 gro_receive. We need to do this each time to overwrite the
setting that would be done in IPv4 gro_receive per the outer
header in IPv6 over Ipv4 encapsulation.
Signed-off-by: Tom Herbert <redacted>
---
net/ipv6/ip6_offload.c | 3 +++
1 file changed, 3 insertions(+)
@@ -261,6 +261,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,/* flush if Traffic Class fields are different */NAPI_GRO_CB(p)->flush|=!!(first_word&htonl(0x0FF00000));NAPI_GRO_CB(p)->flush|=flush;++/* Clear flush_id, there's really no concept of ID in IPv6. */+NAPI_GRO_CB(p)->flush_id=0;}NAPI_GRO_CB(skb)->flush|=flush;
Yeah, I mentioned this problem months ago and apparently forgot to push
the fix.
Unfortunately, probably not the last GRO issue. This whole thing is
really rather fragile and probably easy to break undetected...
From: David Miller <davem@davemloft.net> Date: 2014-09-10 03:27:39
From: Tom Herbert <redacted>
Date: Tue, 9 Sep 2014 11:23:13 -0700
This patch sets populates the IPIP and SIT offload structures with
gro_receive and gro_complete functions. This enables use of GRO
for these. Also, fixed a problem in IPv6 where we were not properly
initializing flush_id.
We're going to need to sort this out, because these functions are
now static after Eric's patches to fix sparse warnings.
You're going to have to respin this with that patch you intended
to add from the previous series that exported these routines.
From: Tom Herbert <hidden> Date: 2014-09-10 04:04:27
On Tue, Sep 9, 2014 at 8:27 PM, David Miller [off-list ref] wrote:
From: Tom Herbert <redacted>
Date: Tue, 9 Sep 2014 11:23:13 -0700
quoted
This patch sets populates the IPIP and SIT offload structures with
gro_receive and gro_complete functions. This enables use of GRO
for these. Also, fixed a problem in IPv6 where we were not properly
initializing flush_id.
We're going to need to sort this out, because these functions are
now static after Eric's patches to fix sparse warnings.
You're going to have to respin this with that patch you intended
to add from the previous series that exported these routines.
I might be missing something, but I believe the functions referred in
this patch series were already static.
From: David Miller <davem@davemloft.net> Date: 2014-09-10 04:32:08
From: Tom Herbert <redacted>
Date: Tue, 9 Sep 2014 21:04:27 -0700
On Tue, Sep 9, 2014 at 8:27 PM, David Miller [off-list ref] wrote:
quoted
From: Tom Herbert <redacted>
Date: Tue, 9 Sep 2014 11:23:13 -0700
quoted
This patch sets populates the IPIP and SIT offload structures with
gro_receive and gro_complete functions. This enables use of GRO
for these. Also, fixed a problem in IPv6 where we were not properly
initializing flush_id.
We're going to need to sort this out, because these functions are
now static after Eric's patches to fix sparse warnings.
You're going to have to respin this with that patch you intended
to add from the previous series that exported these routines.
I might be missing something, but I believe the functions referred in
this patch series were already static.
Oops my bad, let me rereview this...
Yep it's fine, applied, thanks!