Unverified Commit caea2096 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4601 v2 xen-netback: don't produce zero-size SKB frags

parents 94f199d2 9dc65c66
Loading
Loading
Loading
Loading
+38 −6
Original line number Diff line number Diff line
@@ -440,12 +440,25 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
	}

	for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS;
	     shinfo->nr_frags++, gop++, nr_slots--) {
	     nr_slots--) {
		if (unlikely(!txp->size)) {
			unsigned long flags;

			spin_lock_irqsave(&queue->response_lock, flags);
			make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY);
			push_tx_responses(queue);
			spin_unlock_irqrestore(&queue->response_lock, flags);
			++txp;
			continue;
		}

		index = pending_index(queue->pending_cons++);
		pending_idx = queue->pending_ring[index];
		xenvif_tx_create_map_op(queue, pending_idx, txp,
				        txp == first ? extra_count : 0, gop);
		frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx);
		++shinfo->nr_frags;
		++gop;

		if (txp == first)
			txp = txfrags;
@@ -458,20 +471,39 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
		shinfo = skb_shinfo(nskb);
		frags = shinfo->frags;

		for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
		     shinfo->nr_frags++, txp++, gop++) {
		for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) {
			if (unlikely(!txp->size)) {
				unsigned long flags;

				spin_lock_irqsave(&queue->response_lock, flags);
				make_tx_response(queue, txp, 0,
						 XEN_NETIF_RSP_OKAY);
				push_tx_responses(queue);
				spin_unlock_irqrestore(&queue->response_lock,
						       flags);
				continue;
			}

			index = pending_index(queue->pending_cons++);
			pending_idx = queue->pending_ring[index];
			xenvif_tx_create_map_op(queue, pending_idx, txp, 0,
						gop);
			frag_set_pending_idx(&frags[shinfo->nr_frags],
					     pending_idx);
			++shinfo->nr_frags;
			++gop;
		}

		if (shinfo->nr_frags) {
			skb_shinfo(skb)->frag_list = nskb;
	} else if (nskb) {
			nskb = NULL;
		}
	}

	if (nskb) {
		/* A frag_list skb was allocated but it is no longer needed
		 * because enough slots were converted to copy ops above.
		 * because enough slots were converted to copy ops above or some
		 * were empty.
		 */
		kfree_skb(nskb);
	}