aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/netback.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netback/netback.c')
-rw-r--r--drivers/net/xen-netback/netback.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index c4d68d768408..cab9f5257f57 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1349,7 +1349,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
1349{ 1349{
1350 unsigned int offset = skb_headlen(skb); 1350 unsigned int offset = skb_headlen(skb);
1351 skb_frag_t frags[MAX_SKB_FRAGS]; 1351 skb_frag_t frags[MAX_SKB_FRAGS];
1352 int i; 1352 int i, f;
1353 struct ubuf_info *uarg; 1353 struct ubuf_info *uarg;
1354 struct sk_buff *nskb = skb_shinfo(skb)->frag_list; 1354 struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
1355 1355
@@ -1389,23 +1389,25 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
1389 frags[i].page_offset = 0; 1389 frags[i].page_offset = 0;
1390 skb_frag_size_set(&frags[i], len); 1390 skb_frag_size_set(&frags[i], len);
1391 } 1391 }
1392 /* swap out with old one */
1393 memcpy(skb_shinfo(skb)->frags,
1394 frags,
1395 i * sizeof(skb_frag_t));
1396 skb_shinfo(skb)->nr_frags = i;
1397 skb->truesize += i * PAGE_SIZE;
1398 1392
1399 /* remove traces of mapped pages and frag_list */ 1393 /* Copied all the bits from the frag list -- free it. */
1400 skb_frag_list_init(skb); 1394 skb_frag_list_init(skb);
1395 xenvif_skb_zerocopy_prepare(queue, nskb);
1396 kfree_skb(nskb);
1397
1398 /* Release all the original (foreign) frags. */
1399 for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
1400 skb_frag_unref(skb, f);
1401 uarg = skb_shinfo(skb)->destructor_arg; 1401 uarg = skb_shinfo(skb)->destructor_arg;
1402 /* increase inflight counter to offset decrement in callback */ 1402 /* increase inflight counter to offset decrement in callback */
1403 atomic_inc(&queue->inflight_packets); 1403 atomic_inc(&queue->inflight_packets);
1404 uarg->callback(uarg, true); 1404 uarg->callback(uarg, true);
1405 skb_shinfo(skb)->destructor_arg = NULL; 1405 skb_shinfo(skb)->destructor_arg = NULL;
1406 1406
1407 xenvif_skb_zerocopy_prepare(queue, nskb); 1407 /* Fill the skb with the new (local) frags. */
1408 kfree_skb(nskb); 1408 memcpy(skb_shinfo(skb)->frags, frags, i * sizeof(skb_frag_t));
1409 skb_shinfo(skb)->nr_frags = i;
1410 skb->truesize += i * PAGE_SIZE;
1409 1411
1410 return 0; 1412 return 0;
1411} 1413}