Commit 6618ec6f authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents fe3881cf 19424e05
...@@ -1666,6 +1666,8 @@ static const struct net_offload ipip_offload = { ...@@ -1666,6 +1666,8 @@ static const struct net_offload ipip_offload = {
.callbacks = { .callbacks = {
.gso_send_check = inet_gso_send_check, .gso_send_check = inet_gso_send_check,
.gso_segment = inet_gso_segment, .gso_segment = inet_gso_segment,
.gro_receive = inet_gro_receive,
.gro_complete = inet_gro_complete,
}, },
}; };
......
...@@ -261,6 +261,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, ...@@ -261,6 +261,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
/* flush if Traffic Class fields are different */ /* flush if Traffic Class fields are different */
NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000)); NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));
NAPI_GRO_CB(p)->flush |= flush; 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; NAPI_GRO_CB(skb)->flush |= flush;
...@@ -314,6 +317,8 @@ static const struct net_offload sit_offload = { ...@@ -314,6 +317,8 @@ static const struct net_offload sit_offload = {
.callbacks = { .callbacks = {
.gso_send_check = ipv6_gso_send_check, .gso_send_check = ipv6_gso_send_check,
.gso_segment = ipv6_gso_segment, .gso_segment = ipv6_gso_segment,
.gro_receive = ipv6_gro_receive,
.gro_complete = ipv6_gro_complete,
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment