]> Pileus Git - ~andy/linux/blobdiff - drivers/net/xen-netfront.c
vxlan: remove net arg from vxlan[6]_xmit_skb()
[~andy/linux] / drivers / net / xen-netfront.c
index ff7f111fffeed780b1c5581c10561dbe237866ce..36808bf256770a5e02e7674002ed389c7fd8ac19 100644 (file)
@@ -286,8 +286,7 @@ no_skb:
                        break;
                }
 
-               __skb_fill_page_desc(skb, 0, page, 0, 0);
-               skb_shinfo(skb)->nr_frags = 1;
+               skb_add_rx_frag(skb, 0, page, 0, 0, PAGE_SIZE);
                __skb_queue_tail(&np->rx_batch, skb);
        }
 
@@ -831,7 +830,6 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np,
                                  struct sk_buff_head *list)
 {
        struct skb_shared_info *shinfo = skb_shinfo(skb);
-       int nr_frags = shinfo->nr_frags;
        RING_IDX cons = np->rx.rsp_cons;
        struct sk_buff *nskb;
 
@@ -840,19 +838,21 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np,
                        RING_GET_RESPONSE(&np->rx, ++cons);
                skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
 
-               __skb_fill_page_desc(skb, nr_frags,
-                                    skb_frag_page(nfrag),
-                                    rx->offset, rx->status);
+               if (shinfo->nr_frags == MAX_SKB_FRAGS) {
+                       unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
 
-               skb->data_len += rx->status;
+                       BUG_ON(pull_to <= skb_headlen(skb));
+                       __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+               }
+               BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS);
+
+               skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag),
+                               rx->offset, rx->status, PAGE_SIZE);
 
                skb_shinfo(nskb)->nr_frags = 0;
                kfree_skb(nskb);
-
-               nr_frags++;
        }
 
-       shinfo->nr_frags = nr_frags;
        return cons;
 }
 
@@ -933,7 +933,8 @@ static int handle_incoming_queue(struct net_device *dev,
        while ((skb = __skb_dequeue(rxq)) != NULL) {
                int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
 
-               __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+               if (pull_to > skb_headlen(skb))
+                       __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
 
                /* Ethernet work: Delayed to here as it peeks the header. */
                skb->protocol = eth_type_trans(skb, dev);
@@ -1019,16 +1020,10 @@ err:
                skb_shinfo(skb)->frags[0].page_offset = rx->offset;
                skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status);
                skb->data_len = rx->status;
+               skb->len += rx->status;
 
                i = xennet_fill_frags(np, skb, &tmpq);
 
-               /*
-                 * Truesize is the actual allocation size, even if the
-                 * allocation is only partially used.
-                 */
-               skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags;
-               skb->len += skb->data_len;
-
                if (rx->flags & XEN_NETRXF_csum_blank)
                        skb->ip_summed = CHECKSUM_PARTIAL;
                else if (rx->flags & XEN_NETRXF_data_validated)