Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1dc5faf3 authored by Xuan Zhuo's avatar Xuan Zhuo Committed by Greg Kroah-Hartman
Browse files

virtio_net: split free_unused_bufs()



[ Upstream commit 6e345f8c7cd029ad3aaece15ad4425ac26e4eb63 ]

This patch separates two functions for freeing sq buf and rq buf from
free_unused_bufs().

When supporting the enable/disable tx/rq queue in the future, it is
necessary to support separate recovery of a sq buf or a rq buf.

Signed-off-by: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Message-Id: <20220801063902.129329-40-xuanzhuo@linux.alibaba.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Stable-dep-of: f8bb51043945 ("virtio_net: suppress cpu stall when free_unused_bufs")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent b15637e7
Loading
Loading
Loading
Loading
+25 −16
Original line number Diff line number Diff line
@@ -2792,33 +2792,42 @@ static void free_receive_page_frags(struct virtnet_info *vi)
			put_page(vi->rq[i].alloc_frag.page);
}

static void free_unused_bufs(struct virtnet_info *vi)
static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf)
{
	void *buf;
	int i;

	for (i = 0; i < vi->max_queue_pairs; i++) {
		struct virtqueue *vq = vi->sq[i].vq;
		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
	if (!is_xdp_frame(buf))
		dev_kfree_skb(buf);
	else
		xdp_return_frame(ptr_to_xdp(buf));
}
	}

	for (i = 0; i < vi->max_queue_pairs; i++) {
		struct virtqueue *vq = vi->rq[i].vq;
static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf)
{
	struct virtnet_info *vi = vq->vdev->priv;
	int i = vq2rxq(vq);

		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
			if (vi->mergeable_rx_bufs) {
	if (vi->mergeable_rx_bufs)
		put_page(virt_to_head_page(buf));
			} else if (vi->big_packets) {
	else if (vi->big_packets)
		give_pages(&vi->rq[i], buf);
			} else {
	else
		put_page(virt_to_head_page(buf));
}

static void free_unused_bufs(struct virtnet_info *vi)
{
	void *buf;
	int i;

	for (i = 0; i < vi->max_queue_pairs; i++) {
		struct virtqueue *vq = vi->sq[i].vq;
		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
			virtnet_sq_free_unused_buf(vq, buf);
	}

	for (i = 0; i < vi->max_queue_pairs; i++) {
		struct virtqueue *vq = vi->rq[i].vq;
		while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
			virtnet_rq_free_unused_buf(vq, buf);
	}
}