]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/core/skbuff.c
gro: Add page frag support
[karo-tx-linux.git] / net / core / skbuff.c
index 3aafb10325b8c87aacdd8ed459882340664413f6..5110b359c758c2e8abe7d13e5f63f90269fbbd5e 100644 (file)
@@ -2594,6 +2594,17 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
        if (skb_shinfo(p)->frag_list)
                goto merge;
+       else if (!skb_headlen(p) && !skb_headlen(skb) &&
+                skb_shinfo(p)->nr_frags + skb_shinfo(skb)->nr_frags <
+                MAX_SKB_FRAGS) {
+               memcpy(skb_shinfo(p)->frags + skb_shinfo(p)->nr_frags,
+                      skb_shinfo(skb)->frags,
+                      skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
+
+               skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags;
+               NAPI_GRO_CB(skb)->free = 1;
+               goto done;
+       }
 
        headroom = skb_headroom(p);
        nskb = netdev_alloc_skb(p->dev, headroom);
@@ -2628,11 +2639,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        p = nskb;
 
 merge:
-       NAPI_GRO_CB(p)->count++;
        p->prev->next = skb;
        p->prev = skb;
        skb_header_release(skb);
 
+done:
+       NAPI_GRO_CB(p)->count++;
        p->data_len += skb->len;
        p->truesize += skb->len;
        p->len += skb->len;