diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-09 21:29:50 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-09 21:29:50 -0700 |
commit | 6618ec6f742955dcddb71091ec461fbd5fec9fd3 (patch) | |
tree | 3c82e4fea84e7665f8dcde5598a252855b244ebb /net | |
parent | fe3881cf7e09dfb93e4a4c65f44e2d92f92d0022 (diff) | |
parent | 19424e052fb44da2f00d1a868cbb51f3e9f4bbb5 (diff) | |
download | linux-6618ec6f742955dcddb71091ec461fbd5fec9fd3.tar.gz linux-6618ec6f742955dcddb71091ec461fbd5fec9fd3.tar.bz2 linux-6618ec6f742955dcddb71091ec461fbd5fec9fd3.zip |
Merge branch 'ipip_sit_gro'
Tom Herbert says:
====================
net: enable GRO for IPIP and SIT
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
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/af_inet.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_offload.c | 5 |
2 files changed, 7 insertions, 0 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index b537bd94906c..72011cc4c13b 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1666,6 +1666,8 @@ static const struct net_offload ipip_offload = { .callbacks = { .gso_send_check = inet_gso_send_check, .gso_segment = inet_gso_segment, + .gro_receive = inet_gro_receive, + .gro_complete = inet_gro_complete, }, }; diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 5bcda338bcef..9952f3fce30a 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -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; @@ -314,6 +317,8 @@ static const struct net_offload sit_offload = { .callbacks = { .gso_send_check = ipv6_gso_send_check, .gso_segment = ipv6_gso_segment, + .gro_receive = ipv6_gro_receive, + .gro_complete = ipv6_gro_complete, }, }; |