]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Revert "net: preserve IP control block during GSO segmentation"
authorDan Duval <dan.duval@oracle.com>
Thu, 16 Jun 2016 22:45:07 +0000 (18:45 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 22 Jun 2016 05:47:56 +0000 (22:47 -0700)
Orabug: 23522263

This reverts commit a9e889c735eef731df3fce53fb997277f3b0b498.

Yuval Shaia and team discovered that the aforementioned commit
resulted in a substantial (900-to-1) performance loss on a TCP
bandwidth test over IPoIB.  Upstream is aware of the problem
but there is currently no solution in hand, so just revert the
offending commmit.

Note that the original commit purports to fix a kernel crash,
but so far we haven't seen the crash.

Signed-off-by: Dan Duval <dan.duval@oracle.com>
Signed-off-by: Yuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: Ajaykumar Hotchandani <ajaykumar.hotchandani@oracle.com>
Tested-by: Rose Wang <rose.wang@oracle.com>
include/linux/skbuff.h
net/core/dev.c
net/ipv4/ip_output.c
net/openvswitch/datapath.c
net/xfrm/xfrm_output.c

index 1f17abe237251939d0f32fdcc355cf87b2aa1091..4307e20a4a4af840394794858977dcb1af69e24c 100644 (file)
@@ -3320,8 +3320,7 @@ struct skb_gso_cb {
        int     encap_level;
        __u16   csum_start;
 };
-#define SKB_SGO_CB_OFFSET      32
-#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_SGO_CB_OFFSET))
+#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb)
 
 static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
 {
index 185a3398c651d51f9b2ce461e1d818d21a3e7d09..a42b232805a5c5e9fa71a5718f8fb461c85962cd 100644 (file)
@@ -2479,8 +2479,6 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
  *
  *     It may return NULL if the skb requires no segmentation.  This is
  *     only possible when GSO is used for verifying header integrity.
- *
- *     Segmentation preserves SKB_SGO_CB_OFFSET bytes of previous skb cb.
  */
 struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
                                  netdev_features_t features, bool tx_path)
@@ -2495,9 +2493,6 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
                        return ERR_PTR(err);
        }
 
-       BUILD_BUG_ON(SKB_SGO_CB_OFFSET +
-                    sizeof(*SKB_GSO_CB(skb)) > sizeof(skb->cb));
-
        SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb);
        SKB_GSO_CB(skb)->encap_level = 0;
 
index 51573f8a39bca8bd531ea2af738d8cc45e5d2707..fe16f418e775e2c4cd97735866de948e55ecb0db 100644 (file)
@@ -235,7 +235,6 @@ static int ip_finish_output_gso(struct sock *sk, struct sk_buff *skb)
         * from host network stack.
         */
        features = netif_skb_features(skb);
-       BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
        segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
        if (IS_ERR_OR_NULL(segs)) {
                kfree_skb(skb);
index b3fe02a2339e4b5b307ecfd71f9374a27f3afcad..27e14962b5046ca50bfc9c7d1302bd8831aea19a 100644 (file)
@@ -337,10 +337,12 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
        unsigned short gso_type = skb_shinfo(skb)->gso_type;
        struct sw_flow_key later_key;
        struct sk_buff *segs, *nskb;
+       struct ovs_skb_cb ovs_cb;
        int err;
 
-       BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_SGO_CB_OFFSET);
+       ovs_cb = *OVS_CB(skb);
        segs = __skb_gso_segment(skb, NETIF_F_SG, false);
+       *OVS_CB(skb) = ovs_cb;
        if (IS_ERR(segs))
                return PTR_ERR(segs);
        if (segs == NULL)
@@ -358,6 +360,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
        /* Queue all of the segments. */
        skb = segs;
        do {
+               *OVS_CB(skb) = ovs_cb;
                if (gso_type & SKB_GSO_UDP && skb != segs)
                        key = &later_key;
 
index 5097dce5b916661484cb0a1de5820fd8c8e19ae5..fbcedbe33190346a40fc148369757a6ef64a2106 100644 (file)
@@ -153,8 +153,6 @@ static int xfrm_output_gso(struct sock *sk, struct sk_buff *skb)
 {
        struct sk_buff *segs;
 
-       BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
-       BUILD_BUG_ON(sizeof(*IP6CB(skb)) > SKB_SGO_CB_OFFSET);
        segs = skb_gso_segment(skb, 0);
        kfree_skb(skb);
        if (IS_ERR(segs))