bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
To: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	Jason Wang <jasowang@redhat.com>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Jesper Dangaard Brouer <hawk@kernel.org>,
	John Fastabend <john.fastabend@gmail.com>,
	bpf@vger.kernel.org
Subject: [PATCH v5 17/22] virtio_net: support rx/tx queue reset
Date: Mon, 14 Feb 2022 16:14:11 +0800	[thread overview]
Message-ID: <20220214081416.117695-18-xuanzhuo@linux.alibaba.com> (raw)
In-Reply-To: <20220214081416.117695-1-xuanzhuo@linux.alibaba.com>

This patch implements the reset function of the rx, tx queues.

Based on this function, it is possible to modify the ring num of the
queue. And quickly recycle the buffer in the queue.

In the process of the queue disable, in theory, as long as virtio
supports queue reset, there will be no exceptions.

However, in the process of the queue enable, there may be exceptions due to
memory allocation.  In this case, vq is not available, but we still have
to execute napi_enable(). Because napi_disable is similar to a lock,
napi_enable must be called after calling napi_disable.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 123 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 9a1445236e23..a4ffd7cdf623 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -251,6 +251,11 @@ struct padded_vnet_hdr {
 	char padding[4];
 };
 
+static void virtnet_sq_free_unused_bufs(struct virtnet_info *vi,
+					struct send_queue *sq);
+static void virtnet_rq_free_unused_bufs(struct virtnet_info *vi,
+					struct receive_queue *rq);
+
 static bool is_xdp_frame(void *ptr)
 {
 	return (unsigned long)ptr & VIRTIO_XDP_FLAG;
@@ -1369,6 +1374,9 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi)
 {
 	napi_enable(napi);
 
+	if (vq->reset)
+		return;
+
 	/* If all buffers were filled by other side before we napi_enabled, we
 	 * won't get another interrupt, so process any outstanding packets now.
 	 * Call local_bh_enable after to trigger softIRQ processing.
@@ -1413,6 +1421,10 @@ static void refill_work(struct work_struct *work)
 		struct receive_queue *rq = &vi->rq[i];
 
 		napi_disable(&rq->napi);
+		if (rq->vq->reset) {
+			virtnet_napi_enable(rq->vq, &rq->napi);
+			continue;
+		}
 		still_empty = !try_fill_recv(vi, rq, GFP_KERNEL);
 		virtnet_napi_enable(rq->vq, &rq->napi);
 
@@ -1523,6 +1535,9 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
 	if (!sq->napi.weight || is_xdp_raw_buffer_queue(vi, index))
 		return;
 
+	if (sq->vq->reset)
+		return;
+
 	if (__netif_tx_trylock(txq)) {
 		do {
 			virtqueue_disable_cb(sq->vq);
@@ -1769,6 +1784,114 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 }
 
+static int virtnet_rx_vq_disable(struct virtnet_info *vi,
+				 struct receive_queue *rq)
+{
+	int err;
+
+	napi_disable(&rq->napi);
+
+	err = virtio_reset_vq(rq->vq);
+	if (err)
+		goto err;
+
+	virtnet_rq_free_unused_bufs(vi, rq);
+
+	vring_release_virtqueue(rq->vq);
+
+	return 0;
+
+err:
+	virtnet_napi_enable(rq->vq, &rq->napi);
+	return err;
+}
+
+static int virtnet_tx_vq_disable(struct virtnet_info *vi,
+				 struct send_queue *sq)
+{
+	struct netdev_queue *txq;
+	int err, qindex;
+
+	qindex = sq - vi->sq;
+
+	txq = netdev_get_tx_queue(vi->dev, qindex);
+	__netif_tx_lock_bh(txq);
+
+	netif_stop_subqueue(vi->dev, qindex);
+	virtnet_napi_tx_disable(&sq->napi);
+
+	err = virtio_reset_vq(sq->vq);
+	if (err) {
+		virtnet_napi_tx_enable(vi, sq->vq, &sq->napi);
+		netif_start_subqueue(vi->dev, qindex);
+
+		__netif_tx_unlock_bh(txq);
+		return err;
+	}
+	__netif_tx_unlock_bh(txq);
+
+	virtnet_sq_free_unused_bufs(vi, sq);
+
+	vring_release_virtqueue(sq->vq);
+
+	return 0;
+}
+
+static int virtnet_tx_vq_enable(struct virtnet_info *vi, struct send_queue *sq)
+{
+	int err;
+
+	err = virtio_enable_resetq(sq->vq);
+	if (!err)
+		netif_start_subqueue(vi->dev, sq - vi->sq);
+
+	virtnet_napi_tx_enable(vi, sq->vq, &sq->napi);
+
+	return err;
+}
+
+static int virtnet_rx_vq_enable(struct virtnet_info *vi,
+				struct receive_queue *rq)
+{
+	int err;
+
+	err = virtio_enable_resetq(rq->vq);
+
+	virtnet_napi_enable(rq->vq, &rq->napi);
+
+	return err;
+}
+
+static int virtnet_rx_vq_reset(struct virtnet_info *vi, int i)
+{
+	int err;
+
+	err = virtnet_rx_vq_disable(vi, vi->rq + i);
+	if (err)
+		return err;
+
+	err = virtnet_rx_vq_enable(vi, vi->rq + i);
+	if (err)
+		netdev_err(vi->dev,
+			   "enable rx reset vq fail: rx queue index: %d err: %d\n", i, err);
+	return err;
+}
+
+static int virtnet_tx_vq_reset(struct virtnet_info *vi, int i)
+{
+	int err;
+
+	err = virtnet_tx_vq_disable(vi, vi->sq + i);
+	if (err)
+		return err;
+
+	err = virtnet_tx_vq_enable(vi, vi->sq + i);
+	if (err)
+		netdev_err(vi->dev,
+			   "enable tx reset vq fail: tx queue index: %d err: %d\n", i, err);
+	return err;
+}
+
 /*
  * Send command via the control virtqueue and check status.  Commands
  * supported by the hypervisor, as indicated by feature bits, should
-- 
2.31.0


  parent reply	other threads:[~2022-02-14  8:15 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-14  8:13 [PATCH v5 00/22] virtio pci support VIRTIO_F_RING_RESET Xuan Zhuo
2022-02-14  8:13 ` [PATCH v5 01/22] virtio_pci: struct virtio_pci_common_cfg add queue_notify_data Xuan Zhuo
2022-02-14  8:13 ` [PATCH v5 02/22] virtio: queue_reset: add VIRTIO_F_RING_RESET Xuan Zhuo
2022-02-14  8:13 ` [PATCH v5 03/22] virtio_ring: queue_reset: add function vring_setup_virtqueue() Xuan Zhuo
2022-02-14  8:13 ` [PATCH v5 04/22] virtio_ring: queue_reset: split: add __vring_init_virtqueue() Xuan Zhuo
2022-02-14  8:13 ` [PATCH v5 05/22] virtio_ring: queue_reset: split: support enable reset queue Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 06/22] virtio_ring: queue_reset: packed: " Xuan Zhuo
2022-02-16  4:14   ` Jason Wang
2022-02-14  8:14 ` [PATCH v5 07/22] virtio_ring: queue_reset: extract the release function of the vq ring Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 08/22] virtio_ring: queue_reset: add vring_release_virtqueue() Xuan Zhuo
2022-02-16  4:14   ` Jason Wang
2022-02-14  8:14 ` [PATCH v5 09/22] virtio: queue_reset: struct virtio_config_ops add callbacks for queue_reset Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 10/22] virtio_pci: queue_reset: update struct virtio_pci_common_cfg and option functions Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 11/22] virtio_pci: queue_reset: release vq by vp_dev->vqs Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 12/22] virtio_pci: queue_reset: setup_vq() support vring_setup_virtqueue() Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 13/22] virtio_pci: queue_reset: reserve vq->priv for re-enable queue Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 14/22] virtio_pci: queue_reset: support VIRTIO_F_RING_RESET Xuan Zhuo
2022-02-16  4:14   ` Jason Wang
2022-02-16  8:03     ` Xuan Zhuo
2022-02-17  7:25       ` Jason Wang
2022-02-14  8:14 ` [PATCH v5 15/22] virtio: queue_reset: add helper Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 16/22] virtio_net: split free_unused_bufs() Xuan Zhuo
2022-02-14  8:14 ` Xuan Zhuo [this message]
2022-02-16  4:14   ` [PATCH v5 17/22] virtio_net: support rx/tx queue reset Jason Wang
2022-02-16  7:56     ` Xuan Zhuo
2022-02-16  8:35       ` Michael S. Tsirkin
2022-02-16  8:42         ` Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 18/22] virtio: add helper virtqueue_get_vring_max_size() Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 19/22] virtio: add helper virtio_set_max_ring_num() Xuan Zhuo
2022-02-16  4:14   ` Jason Wang
2022-02-16  7:54     ` Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 20/22] virtio_net: set the default max ring num Xuan Zhuo
2022-02-16  4:14   ` Jason Wang
2022-02-16  7:46     ` Xuan Zhuo
2022-02-17  7:21       ` Jason Wang
2022-02-17  9:30         ` Xuan Zhuo
2022-02-21  3:40           ` Jason Wang
2022-02-21  7:00             ` Jason Wang
2022-02-14  8:14 ` [PATCH v5 21/22] virtio_net: get max ring size by virtqueue_get_vring_max_size() Xuan Zhuo
2022-02-14  8:14 ` [PATCH v5 22/22] virtio_net: support set_ringparam Xuan Zhuo
2022-02-16  4:14   ` Jason Wang
2022-02-16  7:21     ` Xuan Zhuo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220214081416.117695-18-xuanzhuo@linux.alibaba.com \
    --to=xuanzhuo@linux.alibaba.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=hawk@kernel.org \
    --cc=jasowang@redhat.com \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).