Merge remote-tracking branches 'asoc/fix/ak4671', 'asoc/fix/control', 'asoc/fix/da732...
[firefly-linux-kernel-4.4.55.git] / drivers / net / xen-netback / netback.c
index f1d84fb1eba8c2d5d5a0fcd10962384be16a2063..cab9f5257f577ffd03c3eb2b7e57398907ee3498 100644 (file)
@@ -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;
 }