* [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP
@ 2013-10-19 18:42 Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 1/6] ipv4: gso: send_check() & segment() cleanups Eric Dumazet
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
This patch serie implements GSO/TSO support for IPIP
David, please note it applies after "ipv4: gso: send_check() & segment() cleanups"
( http://patchwork.ozlabs.org/patch/284714/ )
Broadcom bnx2x driver is now enabled for TSO support of IPIP traffic
Before patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 3357.88 5.09 3.70 2.983 2.167
After patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 8532.40 2.55 7.73 0.588 1.781
Eric Dumazet (6):
ipv4: gso: send_check() & segment() cleanups
net: generalize skb_segment()
ipv4: generalize gre_handle_offloads
ipv4: gso: make inet_gso_segment() stackable
ipip: add GSO/TSO support
bnx2x: add TSO support for IPIP
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +-
include/linux/netdev_features.h | 2 +
include/linux/skbuff.h | 13 ++++--
include/net/gre.h | 8 +++-
include/net/ip_tunnels.h | 3 ++
net/core/dev.c | 2 +
net/core/ethtool.c | 1 +
net/core/skbuff.c | 22 ++-------
net/ipv4/af_inet.c | 58 ++++++++++++++++--------
net/ipv4/gre_demux.c | 29 ------------
net/ipv4/gre_offload.c | 3 +-
net/ipv4/ip_tunnel_core.c | 33 ++++++++++++++
net/ipv4/ipip.c | 11 +++--
net/ipv4/tcp_offload.c | 1 +
net/ipv4/udp_offload.c | 1 +
net/ipv6/ip6_offload.c | 1 +
net/ipv6/udp_offload.c | 1 +
net/mpls/mpls_gso.c | 1 +
18 files changed, 116 insertions(+), 78 deletions(-)
--
1.8.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next 1/6] ipv4: gso: send_check() & segment() cleanups
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
@ 2013-10-19 18:42 ` Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 2/6] net: generalize skb_segment() Eric Dumazet
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
inet_gso_segment() and inet_gso_send_check() are called by
skb_mac_gso_segment() under rcu lock, no need to use
rcu_read_lock() / rcu_read_unlock()
Avoid calling ip_hdr() twice per function.
We can use ip_send_check() helper.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/af_inet.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 35913fb..4f8cd4f 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1254,20 +1254,19 @@ static int inet_gso_send_check(struct sk_buff *skb)
if (ihl < sizeof(*iph))
goto out;
+ proto = iph->protocol;
+
+ /* Warning: after this point, iph might be no longer valid */
if (unlikely(!pskb_may_pull(skb, ihl)))
goto out;
-
__skb_pull(skb, ihl);
+
skb_reset_transport_header(skb);
- iph = ip_hdr(skb);
- proto = iph->protocol;
err = -EPROTONOSUPPORT;
- rcu_read_lock();
ops = rcu_dereference(inet_offloads[proto]);
if (likely(ops && ops->callbacks.gso_send_check))
err = ops->callbacks.gso_send_check(skb);
- rcu_read_unlock();
out:
return err;
@@ -1305,23 +1304,23 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
if (ihl < sizeof(*iph))
goto out;
+ id = ntohs(iph->id);
+ proto = iph->protocol;
+
+ /* Warning: after this point, iph might be no longer valid */
if (unlikely(!pskb_may_pull(skb, ihl)))
goto out;
+ __skb_pull(skb, ihl);
tunnel = !!skb->encapsulation;
- __skb_pull(skb, ihl);
skb_reset_transport_header(skb);
- iph = ip_hdr(skb);
- id = ntohs(iph->id);
- proto = iph->protocol;
+
segs = ERR_PTR(-EPROTONOSUPPORT);
- rcu_read_lock();
ops = rcu_dereference(inet_offloads[proto]);
if (likely(ops && ops->callbacks.gso_segment))
segs = ops->callbacks.gso_segment(skb, features);
- rcu_read_unlock();
if (IS_ERR_OR_NULL(segs))
goto out;
@@ -1339,8 +1338,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
iph->id = htons(id++);
}
iph->tot_len = htons(skb->len - skb->mac_len);
- iph->check = 0;
- iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
+ ip_send_check(iph);
} while ((skb = skb->next));
out:
--
1.8.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 2/6] net: generalize skb_segment()
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 1/6] ipv4: gso: send_check() & segment() cleanups Eric Dumazet
@ 2013-10-19 18:42 ` Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 3/6] ipv4: generalize gre_handle_offloads Eric Dumazet
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
While implementing GSO/TSO support for IPIP, I found skb_segment()
was assuming network header was immediately following mac header.
Its not really true in the case inet_gso_segment() is stacked :
By the time tcp_gso_segment() is called, network header points
to the inner IP header.
Let's instead assume nothing and pick the current offsets found in
original skb, we have skb_headers_offset_update() helper for that.
Also move the csum_start update inside skb_headers_offset_update()
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/skbuff.c | 22 +++++-----------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 8ead744..0ab32fa 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -903,6 +903,9 @@ EXPORT_SYMBOL(skb_clone);
static void skb_headers_offset_update(struct sk_buff *skb, int off)
{
+ /* Only adjust this if it actually is csum_start rather than csum */
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ skb->csum_start += off;
/* {transport,network,mac}_header and tail are relative to skb->head */
skb->transport_header += off;
skb->network_header += off;
@@ -1109,9 +1112,6 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
#endif
skb->tail += off;
skb_headers_offset_update(skb, nhead);
- /* Only adjust this if it actually is csum_start rather than csum */
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- skb->csum_start += nhead;
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
@@ -1176,7 +1176,6 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
NUMA_NO_NODE);
int oldheadroom = skb_headroom(skb);
int head_copy_len, head_copy_off;
- int off;
if (!n)
return NULL;
@@ -1200,11 +1199,7 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
copy_skb_header(n, skb);
- off = newheadroom - oldheadroom;
- if (n->ip_summed == CHECKSUM_PARTIAL)
- n->csum_start += off;
-
- skb_headers_offset_update(n, off);
+ skb_headers_offset_update(n, newheadroom - oldheadroom);
return n;
}
@@ -2837,14 +2832,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
__copy_skb_header(nskb, skb);
nskb->mac_len = skb->mac_len;
- /* nskb and skb might have different headroom */
- if (nskb->ip_summed == CHECKSUM_PARTIAL)
- nskb->csum_start += skb_headroom(nskb) - headroom;
-
- skb_reset_mac_header(nskb);
- skb_set_network_header(nskb, skb->mac_len);
- nskb->transport_header = (nskb->network_header +
- skb_network_header_len(skb));
+ skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom);
skb_copy_from_linear_data_offset(skb, -tnl_hlen,
nskb->data - tnl_hlen,
--
1.8.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 3/6] ipv4: generalize gre_handle_offloads
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 1/6] ipv4: gso: send_check() & segment() cleanups Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 2/6] net: generalize skb_segment() Eric Dumazet
@ 2013-10-19 18:42 ` Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 4/6] ipv4: gso: make inet_gso_segment() stackable Eric Dumazet
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
This patch makes gre_handle_offloads() more generic
and rename it to iptunnel_handle_offloads()
This will be used to add GSO/TSO support to IPIP tunnels.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/gre.h | 8 +++++++-
include/net/ip_tunnels.h | 3 +++
net/ipv4/gre_demux.c | 29 -----------------------------
net/ipv4/ip_tunnel_core.c | 33 +++++++++++++++++++++++++++++++++
4 files changed, 43 insertions(+), 30 deletions(-)
diff --git a/include/net/gre.h b/include/net/gre.h
index 57e4afd..dcd9ae3 100644
--- a/include/net/gre.h
+++ b/include/net/gre.h
@@ -38,7 +38,13 @@ void gre_offload_exit(void);
void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
int hdr_len);
-struct sk_buff *gre_handle_offloads(struct sk_buff *skb, bool gre_csum);
+
+static inline struct sk_buff *gre_handle_offloads(struct sk_buff *skb,
+ bool gre_csum)
+{
+ return iptunnel_handle_offloads(skb, gre_csum, SKB_GSO_GRE);
+}
+
static inline int ip_gre_calc_hlen(__be16 o_flags)
{
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index a0a4a10..732f8c6 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -150,6 +150,9 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
__u8 tos, __u8 ttl, __be16 df, bool xnet);
+struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum,
+ int gso_type_mask);
+
static inline void iptunnel_xmit_stats(int err,
struct net_device_stats *err_stats,
struct pcpu_tstats __percpu *stats)
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c
index 736c9fc3..5893e99 100644
--- a/net/ipv4/gre_demux.c
+++ b/net/ipv4/gre_demux.c
@@ -93,35 +93,6 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
}
EXPORT_SYMBOL_GPL(gre_build_header);
-struct sk_buff *gre_handle_offloads(struct sk_buff *skb, bool gre_csum)
-{
- int err;
-
- if (likely(!skb->encapsulation)) {
- skb_reset_inner_headers(skb);
- skb->encapsulation = 1;
- }
-
- if (skb_is_gso(skb)) {
- err = skb_unclone(skb, GFP_ATOMIC);
- if (unlikely(err))
- goto error;
- skb_shinfo(skb)->gso_type |= SKB_GSO_GRE;
- return skb;
- } else if (skb->ip_summed == CHECKSUM_PARTIAL && gre_csum) {
- err = skb_checksum_help(skb);
- if (unlikely(err))
- goto error;
- } else if (skb->ip_summed != CHECKSUM_PARTIAL)
- skb->ip_summed = CHECKSUM_NONE;
-
- return skb;
-error:
- kfree_skb(skb);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL_GPL(gre_handle_offloads);
-
static __sum16 check_checksum(struct sk_buff *skb)
{
__sum16 csum = 0;
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index c31e3ad..42ffbc8 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -116,3 +116,36 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
return 0;
}
EXPORT_SYMBOL_GPL(iptunnel_pull_header);
+
+struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb,
+ bool csum_help,
+ int gso_type_mask)
+{
+ int err;
+
+ if (likely(!skb->encapsulation)) {
+ skb_reset_inner_headers(skb);
+ skb->encapsulation = 1;
+ }
+
+ if (skb_is_gso(skb)) {
+ err = skb_unclone(skb, GFP_ATOMIC);
+ if (unlikely(err))
+ goto error;
+ skb_shinfo(skb)->gso_type |= gso_type_mask;
+ return skb;
+ }
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL && csum_help) {
+ err = skb_checksum_help(skb);
+ if (unlikely(err))
+ goto error;
+ } else if (skb->ip_summed != CHECKSUM_PARTIAL)
+ skb->ip_summed = CHECKSUM_NONE;
+
+ return skb;
+error:
+ kfree_skb(skb);
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
--
1.8.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 4/6] ipv4: gso: make inet_gso_segment() stackable
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
` (2 preceding siblings ...)
2013-10-19 18:42 ` [PATCH net-next 3/6] ipv4: generalize gre_handle_offloads Eric Dumazet
@ 2013-10-19 18:42 ` Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 5/6] ipip: add GSO/TSO support Eric Dumazet
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
In order to support GSO on IPIP, we need to make
inet_gso_segment() stackable.
It should not assume network header starts right after mac
header.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/skbuff.h | 7 +++++--
net/core/dev.c | 2 ++
net/ipv4/af_inet.c | 25 ++++++++++++++++++-------
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ba74474..cad1e0c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2722,9 +2722,12 @@ static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
/* Keeps track of mac header offset relative to skb->head.
* It is useful for TSO of Tunneling protocol. e.g. GRE.
* For non-tunnel skb it points to skb_mac_header() and for
- * tunnel skb it points to outer mac header. */
+ * tunnel skb it points to outer mac header.
+ * Keeps track of level of encapsulation of network headers.
+ */
struct skb_gso_cb {
- int mac_offset;
+ int mac_offset;
+ int encap_level;
};
#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb)
diff --git a/net/core/dev.c b/net/core/dev.c
index 1b6eadf..0918aad 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2377,6 +2377,8 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
}
SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb);
+ SKB_GSO_CB(skb)->encap_level = 0;
+
skb_reset_mac_header(skb);
skb_reset_mac_len(skb);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 4f8cd4f..5783ab5 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1273,16 +1273,17 @@ out:
}
static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
- netdev_features_t features)
+ netdev_features_t features)
{
struct sk_buff *segs = ERR_PTR(-EINVAL);
const struct net_offload *ops;
+ unsigned int offset = 0;
struct iphdr *iph;
+ bool tunnel;
int proto;
+ int nhoff;
int ihl;
int id;
- unsigned int offset = 0;
- bool tunnel;
if (unlikely(skb_shinfo(skb)->gso_type &
~(SKB_GSO_TCPV4 |
@@ -1296,6 +1297,8 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
0)))
goto out;
+ skb_reset_network_header(skb);
+ nhoff = skb_network_header(skb) - skb_mac_header(skb);
if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
goto out;
@@ -1312,7 +1315,10 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
goto out;
__skb_pull(skb, ihl);
- tunnel = !!skb->encapsulation;
+ tunnel = SKB_GSO_CB(skb)->encap_level > 0;
+ if (tunnel)
+ features = skb->dev->hw_enc_features & netif_skb_features(skb);
+ SKB_GSO_CB(skb)->encap_level += ihl;
skb_reset_transport_header(skb);
@@ -1327,18 +1333,23 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
skb = segs;
do {
- iph = ip_hdr(skb);
+ iph = (struct iphdr *)(skb_mac_header(skb) + nhoff);
if (!tunnel && proto == IPPROTO_UDP) {
iph->id = htons(id);
iph->frag_off = htons(offset >> 3);
if (skb->next != NULL)
iph->frag_off |= htons(IP_MF);
- offset += (skb->len - skb->mac_len - iph->ihl * 4);
+ offset += skb->len - nhoff - ihl;
} else {
iph->id = htons(id++);
}
- iph->tot_len = htons(skb->len - skb->mac_len);
+ iph->tot_len = htons(skb->len - nhoff);
ip_send_check(iph);
+ if (tunnel) {
+ skb_reset_inner_headers(skb);
+ skb->encapsulation = 1;
+ }
+ skb->network_header = (u8 *)iph - skb->head;
} while ((skb = skb->next));
out:
--
1.8.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 5/6] ipip: add GSO/TSO support
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
` (3 preceding siblings ...)
2013-10-19 18:42 ` [PATCH net-next 4/6] ipv4: gso: make inet_gso_segment() stackable Eric Dumazet
@ 2013-10-19 18:42 ` Eric Dumazet
2013-10-19 21:00 ` Dmitry Kravkov
2013-10-19 18:42 ` [PATCH net-next 6/6] bnx2x: add TSO support for IPIP Eric Dumazet
2013-10-19 18:59 ` [PATCH net-next 0/6] net: Implement GSO/TSO " Eric Dumazet
6 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
Now inet_gso_segment() is stackable, its relatively easy to
implement GSO/TSO support for IPIP
Performance results, when segmentation is done after tunnel
device (as no NIC is yet enabled for TSO IPIP support) :
Before patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 3357.88 5.09 3.70 2.983 2.167
After patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 7710.19 4.52 6.62 1.152 1.687
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/netdev_features.h | 2 ++
include/linux/skbuff.h | 6 ++++--
net/core/ethtool.c | 1 +
net/ipv4/af_inet.c | 9 +++++++++
net/ipv4/gre_offload.c | 3 ++-
net/ipv4/ipip.c | 11 ++++++-----
net/ipv4/tcp_offload.c | 1 +
net/ipv4/udp_offload.c | 1 +
net/ipv6/ip6_offload.c | 1 +
net/ipv6/udp_offload.c | 1 +
net/mpls/mpls_gso.c | 1 +
11 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index a2a89a5..8dad68c 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -42,6 +42,7 @@ enum {
NETIF_F_TSO6_BIT, /* ... TCPv6 segmentation */
NETIF_F_FSO_BIT, /* ... FCoE segmentation */
NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */
+ NETIF_F_GSO_IPIP_BIT, /* ... IPIP tunnel with TSO */
NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */
NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */
/**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */
@@ -107,6 +108,7 @@ enum {
#define NETIF_F_RXFCS __NETIF_F(RXFCS)
#define NETIF_F_RXALL __NETIF_F(RXALL)
#define NETIF_F_GSO_GRE __NETIF_F(GSO_GRE)
+#define NETIF_F_GSO_IPIP __NETIF_F(GSO_IPIP)
#define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL)
#define NETIF_F_GSO_MPLS __NETIF_F(GSO_MPLS)
#define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index cad1e0c..6072913 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -318,9 +318,11 @@ enum {
SKB_GSO_GRE = 1 << 6,
- SKB_GSO_UDP_TUNNEL = 1 << 7,
+ SKB_GSO_IPIP = 1 << 7,
- SKB_GSO_MPLS = 1 << 8,
+ SKB_GSO_UDP_TUNNEL = 1 << 8,
+
+ SKB_GSO_MPLS = 1 << 9,
};
#if BITS_PER_LONG > 32
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 78e9d92..8cab774 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -81,6 +81,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
[NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation",
[NETIF_F_FSO_BIT] = "tx-fcoe-segmentation",
[NETIF_F_GSO_GRE_BIT] = "tx-gre-segmentation",
+ [NETIF_F_GSO_IPIP_BIT] = "tx-ipip-segmentation",
[NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation",
[NETIF_F_GSO_MPLS_BIT] = "tx-mpls-segmentation",
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 5783ab5..4049906 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1291,6 +1291,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
SKB_GSO_DODGY |
SKB_GSO_TCP_ECN |
SKB_GSO_GRE |
+ SKB_GSO_IPIP |
SKB_GSO_TCPV6 |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_MPLS |
@@ -1656,6 +1657,13 @@ static struct packet_offload ip_packet_offload __read_mostly = {
},
};
+static const struct net_offload ipip_offload = {
+ .callbacks = {
+ .gso_send_check = inet_gso_send_check,
+ .gso_segment = inet_gso_segment,
+ },
+};
+
static int __init ipv4_offload_init(void)
{
/*
@@ -1667,6 +1675,7 @@ static int __init ipv4_offload_init(void)
pr_crit("%s: Cannot add TCP protocol offload\n", __func__);
dev_add_offload(&ip_packet_offload);
+ inet_add_offload(&ipip_offload, IPPROTO_IPIP);
return 0;
}
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index 55e6bfb..e5d4361 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -39,7 +39,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
SKB_GSO_UDP |
SKB_GSO_DODGY |
SKB_GSO_TCP_ECN |
- SKB_GSO_GRE)))
+ SKB_GSO_GRE |
+ SKB_GSO_IPIP)))
goto out;
if (unlikely(!pskb_may_pull(skb, sizeof(*greh))))
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 7f80fb4..fe3e9f7 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -220,17 +220,17 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb->protocol != htons(ETH_P_IP)))
goto tx_error;
- if (likely(!skb->encapsulation)) {
- skb_reset_inner_headers(skb);
- skb->encapsulation = 1;
- }
+ skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP);
+ if (IS_ERR(skb))
+ goto out;
ip_tunnel_xmit(skb, dev, tiph, tiph->protocol);
return NETDEV_TX_OK;
tx_error:
- dev->stats.tx_errors++;
dev_kfree_skb(skb);
+out:
+ dev->stats.tx_errors++;
return NETDEV_TX_OK;
}
@@ -275,6 +275,7 @@ static const struct net_device_ops ipip_netdev_ops = {
#define IPIP_FEATURES (NETIF_F_SG | \
NETIF_F_FRAGLIST | \
NETIF_F_HIGHDMA | \
+ NETIF_F_GSO_SOFTWARE | \
NETIF_F_HW_CSUM)
static void ipip_tunnel_setup(struct net_device *dev)
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index 8e3113f..dfc96b0 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -56,6 +56,7 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
SKB_GSO_TCP_ECN |
SKB_GSO_TCPV6 |
SKB_GSO_GRE |
+ SKB_GSO_IPIP |
SKB_GSO_MPLS |
SKB_GSO_UDP_TUNNEL |
0) ||
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index f35ecca..83206de 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -52,6 +52,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY |
SKB_GSO_UDP_TUNNEL |
+ SKB_GSO_IPIP |
SKB_GSO_GRE | SKB_GSO_MPLS) ||
!(type & (SKB_GSO_UDP))))
goto out;
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index d82de72..548036a 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -98,6 +98,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
SKB_GSO_DODGY |
SKB_GSO_TCP_ECN |
SKB_GSO_GRE |
+ SKB_GSO_IPIP |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_MPLS |
SKB_GSO_TCPV6 |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 6055951..f63780f 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -64,6 +64,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
SKB_GSO_DODGY |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_GRE |
+ SKB_GSO_IPIP |
SKB_GSO_MPLS) ||
!(type & (SKB_GSO_UDP))))
goto out;
diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c
index 1bec121..851cd88 100644
--- a/net/mpls/mpls_gso.c
+++ b/net/mpls/mpls_gso.c
@@ -33,6 +33,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
SKB_GSO_DODGY |
SKB_GSO_TCP_ECN |
SKB_GSO_GRE |
+ SKB_GSO_IPIP |
SKB_GSO_MPLS)))
goto out;
--
1.8.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 6/6] bnx2x: add TSO support for IPIP
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
` (4 preceding siblings ...)
2013-10-19 18:42 ` [PATCH net-next 5/6] ipip: add GSO/TSO support Eric Dumazet
@ 2013-10-19 18:42 ` Eric Dumazet
2013-10-19 18:59 ` [PATCH net-next 0/6] net: Implement GSO/TSO " Eric Dumazet
6 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Jerry Chu, Tom Herbert, Eric Dumazet
bnx2x driver already handles TSO for GRE, current code
is the same for IPIP.
Performance results : (Note we are now limited by receiver,
as it does not support GRO for IPIP yet)
Before patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 7710.19 4.52 6.62 1.152 1.687
After patch :
lpq83:~# ./netperf -H 7.7.9.84 -Cc
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 7.7.9.84 () port 0 AF_INET
Recv Send Send Utilization Service Demand
Socket Socket Message Elapsed Send Recv Send Recv
Size Size Size Time Throughput local remote local remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB us/KB
87380 16384 16384 10.00 8532.40 2.55 7.73 0.588 1.781
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 8fd3432..6e5b35f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12260,10 +12260,12 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO |
NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
if (!CHIP_IS_E1x(bp)) {
- dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
+ dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL |
+ NETIF_F_GSO_IPIP;
dev->hw_enc_features =
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
+ NETIF_F_GSO_IPIP |
NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
` (5 preceding siblings ...)
2013-10-19 18:42 ` [PATCH net-next 6/6] bnx2x: add TSO support for IPIP Eric Dumazet
@ 2013-10-19 18:59 ` Eric Dumazet
2013-10-19 23:37 ` David Miller
6 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2013-10-19 18:59 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, netdev, Jerry Chu, Tom Herbert
On Sat, 2013-10-19 at 11:42 -0700, Eric Dumazet wrote:
> This patch serie implements GSO/TSO support for IPIP
>
> David, please note it applies after "ipv4: gso: send_check() & segment() cleanups"
> ( http://patchwork.ozlabs.org/patch/284714/ )
Oh well, I meant to say the above patch was _included_ in this patch
set.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 5/6] ipip: add GSO/TSO support
2013-10-19 18:42 ` [PATCH net-next 5/6] ipip: add GSO/TSO support Eric Dumazet
@ 2013-10-19 21:00 ` Dmitry Kravkov
0 siblings, 0 replies; 10+ messages in thread
From: Dmitry Kravkov @ 2013-10-19 21:00 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S. Miller, netdev@vger.kernel.org, Jerry Chu, Tom Herbert
> diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
> index 55e6bfb..e5d4361 100644
> --- a/net/ipv4/gre_offload.c
> +++ b/net/ipv4/gre_offload.c
> @@ -39,7 +39,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
> SKB_GSO_UDP |
> SKB_GSO_DODGY |
> SKB_GSO_TCP_ECN |
> - SKB_GSO_GRE)))
> + SKB_GSO_GRE |
> + SKB_GSO_IPIP)))
> goto out;
Why GRE needs this bit?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP
2013-10-19 18:59 ` [PATCH net-next 0/6] net: Implement GSO/TSO " Eric Dumazet
@ 2013-10-19 23:37 ` David Miller
0 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2013-10-19 23:37 UTC (permalink / raw)
To: eric.dumazet; +Cc: edumazet, netdev, hkchu, therbert
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 19 Oct 2013 11:59:18 -0700
> On Sat, 2013-10-19 at 11:42 -0700, Eric Dumazet wrote:
>> This patch serie implements GSO/TSO support for IPIP
>>
>> David, please note it applies after "ipv4: gso: send_check() & segment() cleanups"
>> ( http://patchwork.ozlabs.org/patch/284714/ )
>
> Oh well, I meant to say the above patch was _included_ in this patch
> set.
I understood what you meant, especially because I just applied the patch
in question :-)
This looks fantastic, all applied, thanks!
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-10-19 23:37 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-19 18:42 [PATCH net-next 0/6] net: Implement GSO/TSO support for IPIP Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 1/6] ipv4: gso: send_check() & segment() cleanups Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 2/6] net: generalize skb_segment() Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 3/6] ipv4: generalize gre_handle_offloads Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 4/6] ipv4: gso: make inet_gso_segment() stackable Eric Dumazet
2013-10-19 18:42 ` [PATCH net-next 5/6] ipip: add GSO/TSO support Eric Dumazet
2013-10-19 21:00 ` Dmitry Kravkov
2013-10-19 18:42 ` [PATCH net-next 6/6] bnx2x: add TSO support for IPIP Eric Dumazet
2013-10-19 18:59 ` [PATCH net-next 0/6] net: Implement GSO/TSO " Eric Dumazet
2013-10-19 23:37 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).