|
@@ -1390,27 +1390,24 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
|
|
|
skb_frag_size_set(&frags[i], len);
|
|
|
}
|
|
|
|
|
|
+ /* Copied all the bits from the frag list -- free it. */
|
|
|
+ skb_frag_list_init(skb);
|
|
|
+ xenvif_skb_zerocopy_prepare(queue, nskb);
|
|
|
+ kfree_skb(nskb);
|
|
|
+
|
|
|
/* Release all the original (foreign) frags. */
|
|
|
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
|
|
|
skb_frag_unref(skb, f);
|
|
|
-
|
|
|
- /* swap out with old one */
|
|
|
- memcpy(skb_shinfo(skb)->frags,
|
|
|
- frags,
|
|
|
- i * sizeof(skb_frag_t));
|
|
|
- skb_shinfo(skb)->nr_frags = i;
|
|
|
- skb->truesize += i * PAGE_SIZE;
|
|
|
-
|
|
|
- /* remove traces of mapped pages and frag_list */
|
|
|
- skb_frag_list_init(skb);
|
|
|
uarg = skb_shinfo(skb)->destructor_arg;
|
|
|
/* increase inflight counter to offset decrement in callback */
|
|
|
atomic_inc(&queue->inflight_packets);
|
|
|
uarg->callback(uarg, true);
|
|
|
skb_shinfo(skb)->destructor_arg = NULL;
|
|
|
|
|
|
- xenvif_skb_zerocopy_prepare(queue, nskb);
|
|
|
- kfree_skb(nskb);
|
|
|
+ /* Fill the skb with the new (local) frags. */
|
|
|
+ memcpy(skb_shinfo(skb)->frags, frags, i * sizeof(skb_frag_t));
|
|
|
+ skb_shinfo(skb)->nr_frags = i;
|
|
|
+ skb->truesize += i * PAGE_SIZE;
|
|
|
|
|
|
return 0;
|
|
|
}
|