All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH vhost v4 0/6] refactor the params of find_vqs()
@ 2024-03-21 10:15 Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null Xuan Zhuo
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

This pathset is splited from the

     http://lore.kernel.org/all/20240229072044.77388-1-xuanzhuo@linux.alibaba.com

That may needs some cycles to discuss. But that notifies too many people.

But just the four commits need to notify so many people.
And four commits are independent. So I split that patch set,
let us review these first.

The patch set try to  refactor the params of find_vqs().
Then we can just change the structure, when introducing new
features.

Thanks.

v4:
  1. remove support for names array entries being null
  2. remove cfg_idx from virtio_vq_config

v3:
  1. fix the bug: "assignment of read-only location '*cfg.names'"

v2:
  1. add kerneldoc for "struct vq_transport_config" @ilpo.jarvinen

v1:
  1. fix some comments from ilpo.jarvinen@linux.intel.com




Xuan Zhuo (6):
  virtio_balloon: remove the dependence where names[] is null
  virtio: remove support for names array entries being null.
  virtio: find_vqs: pass struct instead of multi parameters
  virtio: vring_create_virtqueue: pass struct instead of multi
    parameters
  virtio: vring_new_virtqueue(): pass struct instead of multi parameters
  virtio_ring: simplify the parameters of the funcs related to
    vring_create/new_virtqueue()

 arch/um/drivers/virtio_uml.c             |  33 ++---
 drivers/platform/mellanox/mlxbf-tmfifo.c |  25 ++--
 drivers/remoteproc/remoteproc_virtio.c   |  34 ++---
 drivers/s390/virtio/virtio_ccw.c         |  35 ++---
 drivers/virtio/virtio_balloon.c          |  41 +++---
 drivers/virtio/virtio_mmio.c             |  33 ++---
 drivers/virtio/virtio_pci_common.c       |  62 +++-----
 drivers/virtio/virtio_pci_common.h       |   9 +-
 drivers/virtio/virtio_pci_legacy.c       |  16 ++-
 drivers/virtio/virtio_pci_modern.c       |  37 +++--
 drivers/virtio/virtio_ring.c             | 173 ++++++++---------------
 drivers/virtio/virtio_vdpa.c             |  48 +++----
 include/linux/virtio_config.h            |  75 +++++++---
 include/linux/virtio_ring.h              |  93 +++++++-----
 tools/virtio/virtio_test.c               |   4 +-
 tools/virtio/vringh_test.c               |  28 ++--
 16 files changed, 351 insertions(+), 395 deletions(-)

--
2.32.0.3.g01195cf9f


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
@ 2024-03-21 10:15 ` Xuan Zhuo
  2024-03-22 11:56   ` David Hildenbrand
  2024-03-22 19:16   ` Daniel Verkamp
  2024-03-21 10:15 ` [PATCH vhost v4 2/6] virtio: remove support for names array entries being null Xuan Zhuo
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

Currently, the init_vqs function within the virtio_balloon driver relies
on the condition that certain names array entries are null in order to
skip the initialization of some virtual queues (vqs). This behavior is
unique to this part of the codebase. In an upcoming commit, we plan to
eliminate this dependency by removing the function entirely. Therefore,
with this change, we are ensuring that the virtio_balloon no longer
depends on the aforementioned function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/virtio/virtio_balloon.c | 41 +++++++++++++++------------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 1f5b3dd31fcf..becc12a05407 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -531,49 +531,46 @@ static int init_vqs(struct virtio_balloon *vb)
 	struct virtqueue *vqs[VIRTIO_BALLOON_VQ_MAX];
 	vq_callback_t *callbacks[VIRTIO_BALLOON_VQ_MAX];
 	const char *names[VIRTIO_BALLOON_VQ_MAX];
-	int err;
+	int err, nvqs, idx;
 
-	/*
-	 * Inflateq and deflateq are used unconditionally. The names[]
-	 * will be NULL if the related feature is not enabled, which will
-	 * cause no allocation for the corresponding virtqueue in find_vqs.
-	 */
 	callbacks[VIRTIO_BALLOON_VQ_INFLATE] = balloon_ack;
 	names[VIRTIO_BALLOON_VQ_INFLATE] = "inflate";
 	callbacks[VIRTIO_BALLOON_VQ_DEFLATE] = balloon_ack;
 	names[VIRTIO_BALLOON_VQ_DEFLATE] = "deflate";
-	callbacks[VIRTIO_BALLOON_VQ_STATS] = NULL;
-	names[VIRTIO_BALLOON_VQ_STATS] = NULL;
-	callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
-	names[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
-	names[VIRTIO_BALLOON_VQ_REPORTING] = NULL;
+
+	nvqs = VIRTIO_BALLOON_VQ_DEFLATE + 1;
 
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
-		names[VIRTIO_BALLOON_VQ_STATS] = "stats";
-		callbacks[VIRTIO_BALLOON_VQ_STATS] = stats_request;
+		names[nvqs] = "stats";
+		callbacks[nvqs] = stats_request;
+		++nvqs;
 	}
 
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
-		names[VIRTIO_BALLOON_VQ_FREE_PAGE] = "free_page_vq";
-		callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
+		names[nvqs] = "free_page_vq";
+		callbacks[nvqs] = NULL;
+		++nvqs;
 	}
 
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING)) {
-		names[VIRTIO_BALLOON_VQ_REPORTING] = "reporting_vq";
-		callbacks[VIRTIO_BALLOON_VQ_REPORTING] = balloon_ack;
+		names[nvqs] = "reporting_vq";
+		callbacks[nvqs] = balloon_ack;
+		++nvqs;
 	}
 
-	err = virtio_find_vqs(vb->vdev, VIRTIO_BALLOON_VQ_MAX, vqs,
-			      callbacks, names, NULL);
+	err = virtio_find_vqs(vb->vdev, nvqs, vqs, callbacks, names, NULL);
 	if (err)
 		return err;
 
 	vb->inflate_vq = vqs[VIRTIO_BALLOON_VQ_INFLATE];
 	vb->deflate_vq = vqs[VIRTIO_BALLOON_VQ_DEFLATE];
+
+	idx = VIRTIO_BALLOON_VQ_DEFLATE + 1;
+
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
 		struct scatterlist sg;
 		unsigned int num_stats;
-		vb->stats_vq = vqs[VIRTIO_BALLOON_VQ_STATS];
+		vb->stats_vq = vqs[idx++];
 
 		/*
 		 * Prime this virtqueue with one buffer so the hypervisor can
@@ -593,10 +590,10 @@ static int init_vqs(struct virtio_balloon *vb)
 	}
 
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
-		vb->free_page_vq = vqs[VIRTIO_BALLOON_VQ_FREE_PAGE];
+		vb->free_page_vq = vqs[idx++];
 
 	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING))
-		vb->reporting_vq = vqs[VIRTIO_BALLOON_VQ_REPORTING];
+		vb->reporting_vq = vqs[idx++];
 
 	return 0;
 }
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH vhost v4 2/6] virtio: remove support for names array entries being null.
  2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null Xuan Zhuo
@ 2024-03-21 10:15 ` Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters Xuan Zhuo
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

commit 6457f126c888 ("virtio: support reserved vqs") introduced this
support. Multiqueue virtio-net use 2N as ctrl vq finally, so the logic
doesn't apply. And not one uses this.

On the other side, that makes some trouble for us to refactor the
find_vqs() params.

So I remove this support.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 arch/um/drivers/virtio_uml.c             | 5 -----
 drivers/platform/mellanox/mlxbf-tmfifo.c | 4 ----
 drivers/remoteproc/remoteproc_virtio.c   | 5 -----
 drivers/s390/virtio/virtio_ccw.c         | 5 -----
 drivers/virtio/virtio_mmio.c             | 5 -----
 drivers/virtio/virtio_pci_common.c       | 9 ---------
 drivers/virtio/virtio_vdpa.c             | 5 -----
 include/linux/virtio_config.h            | 1 -
 8 files changed, 39 deletions(-)

diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 8adca2000e51..1d1e8654b7fc 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -1031,11 +1031,6 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 		return rc;
 
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
-
 		vqs[i] = vu_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
 				     ctx ? ctx[i] : false);
 		if (IS_ERR(vqs[i])) {
diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
index b8d1e32e97eb..f4639331f32e 100644
--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -1072,10 +1072,6 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
 		return -EINVAL;
 
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			ret = -EINVAL;
-			goto error;
-		}
 		vring = &tm_vdev->vrings[i];
 
 		/* zero vring */
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 83d76915a6ad..cd71827d67af 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -190,11 +190,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
 	int i, ret, queue_idx = 0;
 
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
-
 		vqs[i] = rp_find_vq(vdev, queue_idx++, callbacks[i], names[i],
 				    ctx ? ctx[i] : false);
 		if (IS_ERR(vqs[i])) {
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index ac67576301bf..773f16c294d9 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -667,11 +667,6 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 		return -ENOMEM;
 
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
-
 		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
 					     names[i], ctx ? ctx[i] : false,
 					     ccw);
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 59892a31cf76..a95c98cca63e 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -510,11 +510,6 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
 		enable_irq_wake(irq);
 
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
-
 		vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
 				     ctx ? ctx[i] : false);
 		if (IS_ERR(vqs[i])) {
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index b655fccaf773..783758672ef9 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -317,11 +317,6 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
 	vp_dev->per_vq_vectors = per_vq_vectors;
 	allocated_vectors = vp_dev->msix_used_vectors;
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
-
 		if (!callbacks[i])
 			msix_vec = VIRTIO_MSI_NO_VECTOR;
 		else if (vp_dev->per_vq_vectors)
@@ -377,10 +372,6 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
 	vp_dev->intx_enabled = 1;
 	vp_dev->per_vq_vectors = false;
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
 		vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
 				     ctx ? ctx[i] : false,
 				     VIRTIO_MSI_NO_VECTOR);
diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
index e803db0da307..c1a3fbacd463 100644
--- a/drivers/virtio/virtio_vdpa.c
+++ b/drivers/virtio/virtio_vdpa.c
@@ -379,11 +379,6 @@ static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
 	}
 
 	for (i = 0; i < nvqs; ++i) {
-		if (!names[i]) {
-			vqs[i] = NULL;
-			continue;
-		}
-
 		vqs[i] = virtio_vdpa_setup_vq(vdev, queue_idx++,
 					      callbacks[i], names[i], ctx ?
 					      ctx[i] : false);
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index da9b271b54db..d362a29550fa 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -56,7 +56,6 @@ typedef void vq_callback_t(struct virtqueue *);
  *	callbacks: array of callbacks, for each virtqueue
  *		include a NULL entry for vqs that do not need a callback
  *	names: array of virtqueue names (mainly for debugging)
- *		include a NULL entry for vqs unused by driver
  *	Returns 0 on success or error status
  * @del_vqs: free virtqueues found by find_vqs().
  * @synchronize_cbs: synchronize with the virtqueue callbacks (optional)
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters
  2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 2/6] virtio: remove support for names array entries being null Xuan Zhuo
@ 2024-03-21 10:15 ` Xuan Zhuo
  2024-03-22 14:10   ` kernel test robot
  2024-03-23  0:29   ` kernel test robot
  2024-03-21 10:15 ` [PATCH vhost v4 4/6] virtio: vring_create_virtqueue: " Xuan Zhuo
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

Now, we pass multi parameters to find_vqs. These parameters
may work for transport or work for vring.

And find_vqs has multi implements in many places:

 arch/um/drivers/virtio_uml.c
 drivers/platform/mellanox/mlxbf-tmfifo.c
 drivers/remoteproc/remoteproc_virtio.c
 drivers/s390/virtio/virtio_ccw.c
 drivers/virtio/virtio_mmio.c
 drivers/virtio/virtio_pci_legacy.c
 drivers/virtio/virtio_pci_modern.c
 drivers/virtio/virtio_vdpa.c

Every time, we try to add a new parameter, that is difficult.
We must change every find_vqs implement.

One the other side, if we want to pass a parameter to vring,
we must change the call path from transport to vring.
Too many functions need to be changed.

So it is time to refactor the find_vqs. We pass a structure
cfg to find_vqs(), that will be passed to vring by transport.

Because the vp_modern_create_avq() use the "const char *names[]",
and the virtio_uml.c changes the name in the subsequent commit, so
change the "names" inside the virtio_vq_config from "const char *const
*names" to "const char **names".

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 arch/um/drivers/virtio_uml.c             | 20 +++----
 drivers/platform/mellanox/mlxbf-tmfifo.c | 11 ++--
 drivers/remoteproc/remoteproc_virtio.c   | 26 ++++-----
 drivers/s390/virtio/virtio_ccw.c         | 26 ++++-----
 drivers/virtio/virtio_mmio.c             | 24 ++++----
 drivers/virtio/virtio_pci_common.c       | 53 +++++++----------
 drivers/virtio/virtio_pci_common.h       |  9 +--
 drivers/virtio/virtio_pci_legacy.c       | 11 ++--
 drivers/virtio/virtio_pci_modern.c       | 32 +++++-----
 drivers/virtio/virtio_vdpa.c             | 34 +++++------
 include/linux/virtio_config.h            | 74 ++++++++++++++++++------
 11 files changed, 166 insertions(+), 154 deletions(-)

diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 1d1e8654b7fc..140560de2940 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -937,8 +937,8 @@ static int vu_setup_vq_call_fd(struct virtio_uml_device *vu_dev,
 }
 
 static struct virtqueue *vu_setup_vq(struct virtio_device *vdev,
-				     unsigned index, vq_callback_t *callback,
-				     const char *name, bool ctx)
+				     unsigned index,
+				     struct virtio_vq_config *cfg)
 {
 	struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
 	struct platform_device *pdev = vu_dev->pdev;
@@ -953,10 +953,12 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev,
 		goto error_kzalloc;
 	}
 	snprintf(info->name, sizeof(info->name), "%s.%d-%s", pdev->name,
-		 pdev->id, name);
+		 pdev->id, cfg->names[index]);
 
 	vq = vring_create_virtqueue(index, num, PAGE_SIZE, vdev, true, true,
-				    ctx, vu_notify, callback, info->name);
+				    cfg->ctx ? cfg->ctx[index] : false,
+				    vu_notify,
+				    cfg->callbacks[index], info->name);
 	if (!vq) {
 		rc = -ENOMEM;
 		goto error_create;
@@ -1013,12 +1015,11 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev,
 	return ERR_PTR(rc);
 }
 
-static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
-		       struct virtqueue *vqs[], vq_callback_t *callbacks[],
-		       const char * const names[], const bool *ctx,
-		       struct irq_affinity *desc)
+static int vu_find_vqs(struct virtio_device *vdev, struct virtio_vq_config *cfg)
 {
 	struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
+	struct virtqueue **vqs = cfg->vqs;
+	unsigned int nvqs = cfg->nvqs;
 	int i, queue_idx = 0, rc;
 	struct virtqueue *vq;
 
@@ -1031,8 +1032,7 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 		return rc;
 
 	for (i = 0; i < nvqs; ++i) {
-		vqs[i] = vu_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-				     ctx ? ctx[i] : false);
+		vqs[i] = vu_setup_vq(vdev, queue_idx++, cfg);
 		if (IS_ERR(vqs[i])) {
 			rc = PTR_ERR(vqs[i]);
 			goto error_setup;
diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
index f4639331f32e..10e74eb95d31 100644
--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -1056,15 +1056,12 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev)
 
 /* Create and initialize the virtual queues. */
 static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
-					unsigned int nvqs,
-					struct virtqueue *vqs[],
-					vq_callback_t *callbacks[],
-					const char * const names[],
-					const bool *ctx,
-					struct irq_affinity *desc)
+					struct virtio_vq_config *cfg)
 {
 	struct mlxbf_tmfifo_vdev *tm_vdev = mlxbf_vdev_to_tmfifo(vdev);
+	struct virtqueue **vqs = cfg->vqs;
 	struct mlxbf_tmfifo_vring *vring;
+	unsigned int nvqs = cfg->nvqs;
 	struct virtqueue *vq;
 	int i, ret, size;
 
@@ -1080,7 +1077,7 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
 		vq = vring_new_virtqueue(i, vring->num, vring->align, vdev,
 					 false, false, vring->va,
 					 mlxbf_tmfifo_virtio_notify,
-					 callbacks[i], names[i]);
+					 cfg->callbacks[i], cfg->names[i]);
 		if (!vq) {
 			dev_err(&vdev->dev, "vring_new_virtqueue failed\n");
 			ret = -ENOMEM;
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index cd71827d67af..3da1529e445d 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -102,8 +102,7 @@ EXPORT_SYMBOL(rproc_vq_interrupt);
 
 static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
 				    unsigned int id,
-				    void (*callback)(struct virtqueue *vq),
-				    const char *name, bool ctx)
+				    struct virtio_vq_config *cfg)
 {
 	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
 	struct rproc *rproc = vdev_to_rproc(vdev);
@@ -119,9 +118,6 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
 	if (id >= ARRAY_SIZE(rvdev->vring))
 		return ERR_PTR(-EINVAL);
 
-	if (!name)
-		return NULL;
-
 	/* Search allocated memory region by name */
 	mem = rproc_find_carveout_by_name(rproc, "vdev%dvring%d", rvdev->index,
 					  id);
@@ -143,10 +139,12 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
 	 * Create the new vq, and tell virtio we're not interested in
 	 * the 'weak' smp barriers, since we're talking with a real device.
 	 */
-	vq = vring_new_virtqueue(id, num, rvring->align, vdev, false, ctx,
-				 addr, rproc_virtio_notify, callback, name);
+	vq = vring_new_virtqueue(id, num, rvring->align, vdev, false,
+				 cfg->ctx ? cfg->ctx[id] : false,
+				 addr, rproc_virtio_notify, cfg->callbacks[id],
+				 cfg->names[id]);
 	if (!vq) {
-		dev_err(dev, "vring_new_virtqueue %s failed\n", name);
+		dev_err(dev, "vring_new_virtqueue %s failed\n", cfg->names[id]);
 		rproc_free_vring(rvring);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -180,18 +178,14 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
 	__rproc_virtio_del_vqs(vdev);
 }
 
-static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
-				 struct virtqueue *vqs[],
-				 vq_callback_t *callbacks[],
-				 const char * const names[],
-				 const bool * ctx,
-				 struct irq_affinity *desc)
+static int rproc_virtio_find_vqs(struct virtio_device *vdev, struct virtio_vq_config *cfg)
 {
+	struct virtqueue **vqs = cfg->vqs;
+	unsigned int nvqs = cfg->nvqs;
 	int i, ret, queue_idx = 0;
 
 	for (i = 0; i < nvqs; ++i) {
-		vqs[i] = rp_find_vq(vdev, queue_idx++, callbacks[i], names[i],
-				    ctx ? ctx[i] : false);
+		vqs[i] = rp_find_vq(vdev, queue_idx++, cfg);
 		if (IS_ERR(vqs[i])) {
 			ret = PTR_ERR(vqs[i]);
 			goto error;
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index 773f16c294d9..3d6a78bd9c96 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -499,9 +499,8 @@ static void virtio_ccw_del_vqs(struct virtio_device *vdev)
 }
 
 static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
-					     int i, vq_callback_t *callback,
-					     const char *name, bool ctx,
-					     struct ccw1 *ccw)
+					     int i, struct ccw1 *ccw,
+					     struct virtio_vq_config *cfg)
 {
 	struct virtio_ccw_device *vcdev = to_vc_device(vdev);
 	bool (*notify)(struct virtqueue *vq);
@@ -538,8 +537,11 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
 	}
 	may_reduce = vcdev->revision > 0;
 	vq = vring_create_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN,
-				    vdev, true, may_reduce, ctx,
-				    notify, callback, name);
+				    vdev, true, may_reduce,
+				    cfg->ctx ? cfg->ctx[i] : false,
+				    notify,
+				    cfg->callbacks[i],
+				    cfg->names[i]);
 
 	if (!vq) {
 		/* For now, we fail if we can't get the requested size. */
@@ -650,15 +652,13 @@ static int virtio_ccw_register_adapter_ind(struct virtio_ccw_device *vcdev,
 	return ret;
 }
 
-static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
-			       struct virtqueue *vqs[],
-			       vq_callback_t *callbacks[],
-			       const char * const names[],
-			       const bool *ctx,
-			       struct irq_affinity *desc)
+static int virtio_ccw_find_vqs(struct virtio_device *vdev,
+			       struct virtio_vq_config *cfg)
 {
 	struct virtio_ccw_device *vcdev = to_vc_device(vdev);
+	struct virtqueue **vqs = cfg->vqs;
 	unsigned long *indicatorp = NULL;
+	unsigned int nvqs = cfg->nvqs;
 	int ret, i, queue_idx = 0;
 	struct ccw1 *ccw;
 
@@ -667,9 +667,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
 		return -ENOMEM;
 
 	for (i = 0; i < nvqs; ++i) {
-		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
-					     names[i], ctx ? ctx[i] : false,
-					     ccw);
+		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, ccw, cfg);
 		if (IS_ERR(vqs[i])) {
 			ret = PTR_ERR(vqs[i]);
 			vqs[i] = NULL;
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index a95c98cca63e..14bb1d862151 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -370,8 +370,7 @@ static void vm_synchronize_cbs(struct virtio_device *vdev)
 }
 
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int index,
-				  void (*callback)(struct virtqueue *vq),
-				  const char *name, bool ctx)
+				     struct virtio_vq_config *cfg)
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 	bool (*notify)(struct virtqueue *vq);
@@ -386,9 +385,6 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
 	else
 		notify = vm_notify;
 
-	if (!name)
-		return NULL;
-
 	/* Select the queue we're interested in */
 	writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
 
@@ -414,7 +410,11 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
 
 	/* Create the vring */
 	vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
-				 true, true, ctx, notify, callback, name);
+				    true, true,
+				    cfg->ctx ? cfg->ctx[index] : false,
+				    notify,
+				    cfg->callbacks[index],
+				    cfg->names[index]);
 	if (!vq) {
 		err = -ENOMEM;
 		goto error_new_virtqueue;
@@ -487,15 +487,12 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
 	return ERR_PTR(err);
 }
 
-static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
-		       struct virtqueue *vqs[],
-		       vq_callback_t *callbacks[],
-		       const char * const names[],
-		       const bool *ctx,
-		       struct irq_affinity *desc)
+static int vm_find_vqs(struct virtio_device *vdev, struct virtio_vq_config *cfg)
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 	int irq = platform_get_irq(vm_dev->pdev, 0);
+	struct virtqueue **vqs = cfg->vqs;
+	unsigned int nvqs = cfg->nvqs;
 	int i, err, queue_idx = 0;
 
 	if (irq < 0)
@@ -510,8 +507,7 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
 		enable_irq_wake(irq);
 
 	for (i = 0; i < nvqs; ++i) {
-		vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-				     ctx ? ctx[i] : false);
+		vqs[i] = vm_setup_vq(vdev, queue_idx++, cfg);
 		if (IS_ERR(vqs[i])) {
 			vm_del_vqs(vdev);
 			return PTR_ERR(vqs[i]);
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 783758672ef9..2a5fc5498115 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -172,9 +172,7 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
 }
 
 static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned int index,
-				     void (*callback)(struct virtqueue *vq),
-				     const char *name,
-				     bool ctx,
+				     struct virtio_vq_config *cfg,
 				     u16 msix_vec)
 {
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
@@ -186,13 +184,12 @@ static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned int in
 	if (!info)
 		return ERR_PTR(-ENOMEM);
 
-	vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, ctx,
-			      msix_vec);
+	vq = vp_dev->setup_vq(vp_dev, info, index, cfg, msix_vec);
 	if (IS_ERR(vq))
 		goto out_info;
 
 	info->vq = vq;
-	if (callback) {
+	if (cfg->callbacks[index]) {
 		spin_lock_irqsave(&vp_dev->lock, flags);
 		list_add(&info->node, &vp_dev->virtqueues);
 		spin_unlock_irqrestore(&vp_dev->lock, flags);
@@ -284,15 +281,15 @@ void vp_del_vqs(struct virtio_device *vdev)
 	vp_dev->vqs = NULL;
 }
 
-static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
-		struct virtqueue *vqs[], vq_callback_t *callbacks[],
-		const char * const names[], bool per_vq_vectors,
-		const bool *ctx,
-		struct irq_affinity *desc)
+static int vp_find_vqs_msix(struct virtio_device *vdev,
+			    struct virtio_vq_config *cfg,
+			    bool per_vq_vectors)
 {
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
 	u16 msix_vec;
 	int i, err, nvectors, allocated_vectors, queue_idx = 0;
+	struct virtqueue **vqs = cfg->vqs;
+	unsigned int nvqs = cfg->nvqs;
 
 	vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL);
 	if (!vp_dev->vqs)
@@ -302,7 +299,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
 		/* Best option: one for change interrupt, one per vq. */
 		nvectors = 1;
 		for (i = 0; i < nvqs; ++i)
-			if (names[i] && callbacks[i])
+			if (cfg->names[i] && cfg->callbacks[i])
 				++nvectors;
 	} else {
 		/* Second best: one for change, shared for all vqs. */
@@ -310,22 +307,21 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
 	}
 
 	err = vp_request_msix_vectors(vdev, nvectors, per_vq_vectors,
-				      per_vq_vectors ? desc : NULL);
+				      per_vq_vectors ? cfg->desc : NULL);
 	if (err)
 		goto error_find;
 
 	vp_dev->per_vq_vectors = per_vq_vectors;
 	allocated_vectors = vp_dev->msix_used_vectors;
 	for (i = 0; i < nvqs; ++i) {
-		if (!callbacks[i])
+		if (!cfg->callbacks[i])
 			msix_vec = VIRTIO_MSI_NO_VECTOR;
 		else if (vp_dev->per_vq_vectors)
 			msix_vec = allocated_vectors++;
 		else
 			msix_vec = VP_MSIX_VQ_VECTOR;
-		vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-				     ctx ? ctx[i] : false,
-				     msix_vec);
+
+		vqs[i] = vp_setup_vq(vdev, queue_idx++, cfg, msix_vec);
 		if (IS_ERR(vqs[i])) {
 			err = PTR_ERR(vqs[i]);
 			goto error_find;
@@ -338,7 +334,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
 		snprintf(vp_dev->msix_names[msix_vec],
 			 sizeof *vp_dev->msix_names,
 			 "%s-%s",
-			 dev_name(&vp_dev->vdev.dev), names[i]);
+			 dev_name(&vp_dev->vdev.dev), cfg->names[i]);
 		err = request_irq(pci_irq_vector(vp_dev->pci_dev, msix_vec),
 				  vring_interrupt, 0,
 				  vp_dev->msix_names[msix_vec],
@@ -353,11 +349,11 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
 	return err;
 }
 
-static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
-		struct virtqueue *vqs[], vq_callback_t *callbacks[],
-		const char * const names[], const bool *ctx)
+static int vp_find_vqs_intx(struct virtio_device *vdev, struct virtio_vq_config *cfg)
 {
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+	struct virtqueue **vqs = cfg->vqs;
+	unsigned int nvqs = cfg->nvqs;
 	int i, err, queue_idx = 0;
 
 	vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL);
@@ -372,9 +368,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
 	vp_dev->intx_enabled = 1;
 	vp_dev->per_vq_vectors = false;
 	for (i = 0; i < nvqs; ++i) {
-		vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-				     ctx ? ctx[i] : false,
-				     VIRTIO_MSI_NO_VECTOR);
+		vqs[i] = vp_setup_vq(vdev, queue_idx++, cfg, VIRTIO_MSI_NO_VECTOR);
 		if (IS_ERR(vqs[i])) {
 			err = PTR_ERR(vqs[i]);
 			goto out_del_vqs;
@@ -388,26 +382,23 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
 }
 
 /* the config->find_vqs() implementation */
-int vp_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
-		struct virtqueue *vqs[], vq_callback_t *callbacks[],
-		const char * const names[], const bool *ctx,
-		struct irq_affinity *desc)
+int vp_find_vqs(struct virtio_device *vdev, struct virtio_vq_config *cfg)
 {
 	int err;
 
 	/* Try MSI-X with one vector per queue. */
-	err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, ctx, desc);
+	err = vp_find_vqs_msix(vdev, cfg, true);
 	if (!err)
 		return 0;
 	/* Fallback: MSI-X with one vector for config, one shared for queues. */
-	err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, ctx, desc);
+	err = vp_find_vqs_msix(vdev, cfg, false);
 	if (!err)
 		return 0;
 	/* Is there an interrupt? If not give up. */
 	if (!(to_vp_device(vdev)->pci_dev->irq))
 		return err;
 	/* Finally fall back to regular interrupts. */
-	return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, ctx);
+	return vp_find_vqs_intx(vdev, cfg);
 }
 
 const char *vp_bus_name(struct virtio_device *vdev)
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h
index 7fef52bee455..5ba8b82fb765 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -95,9 +95,7 @@ struct virtio_pci_device {
 	struct virtqueue *(*setup_vq)(struct virtio_pci_device *vp_dev,
 				      struct virtio_pci_vq_info *info,
 				      unsigned int idx,
-				      void (*callback)(struct virtqueue *vq),
-				      const char *name,
-				      bool ctx,
+				      struct virtio_vq_config *vq_cfg,
 				      u16 msix_vec);
 	void (*del_vq)(struct virtio_pci_vq_info *info);
 
@@ -126,10 +124,7 @@ bool vp_notify(struct virtqueue *vq);
 /* the config->del_vqs() implementation */
 void vp_del_vqs(struct virtio_device *vdev);
 /* the config->find_vqs() implementation */
-int vp_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
-		struct virtqueue *vqs[], vq_callback_t *callbacks[],
-		const char * const names[], const bool *ctx,
-		struct irq_affinity *desc);
+int vp_find_vqs(struct virtio_device *vdev, struct virtio_vq_config *cfg);
 const char *vp_bus_name(struct virtio_device *vdev);
 
 /* Setup the affinity for a virtqueue:
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index d9cbb02b35a1..a8de653dd7a7 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -110,9 +110,7 @@ static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector)
 static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 				  struct virtio_pci_vq_info *info,
 				  unsigned int index,
-				  void (*callback)(struct virtqueue *vq),
-				  const char *name,
-				  bool ctx,
+				  struct virtio_vq_config *cfg,
 				  u16 msix_vec)
 {
 	struct virtqueue *vq;
@@ -130,8 +128,11 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 	/* create the vring */
 	vq = vring_create_virtqueue(index, num,
 				    VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev,
-				    true, false, ctx,
-				    vp_notify, callback, name);
+				    true, false,
+				    cfg->ctx ? cfg->ctx[index] : false,
+				    vp_notify,
+				    cfg->callbacks[index],
+				    cfg->names[index]);
 	if (!vq)
 		return ERR_PTR(-ENOMEM);
 
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index f62b530aa3b5..bcb829ffec64 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -530,9 +530,7 @@ static bool vp_notify_with_data(struct virtqueue *vq)
 static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 				  struct virtio_pci_vq_info *info,
 				  unsigned int index,
-				  void (*callback)(struct virtqueue *vq),
-				  const char *name,
-				  bool ctx,
+				  struct virtio_vq_config *cfg,
 				  u16 msix_vec)
 {
 
@@ -563,8 +561,11 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 	/* create the vring */
 	vq = vring_create_virtqueue(index, num,
 				    SMP_CACHE_BYTES, &vp_dev->vdev,
-				    true, true, ctx,
-				    notify, callback, name);
+				    true, true,
+				    cfg->ctx ? cfg->ctx[index] : false,
+				    notify,
+				    cfg->callbacks[index],
+				    cfg->names[index]);
 	if (!vq)
 		return ERR_PTR(-ENOMEM);
 
@@ -593,15 +594,11 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 	return ERR_PTR(err);
 }
 
-static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
-			      struct virtqueue *vqs[],
-			      vq_callback_t *callbacks[],
-			      const char * const names[], const bool *ctx,
-			      struct irq_affinity *desc)
+static int vp_modern_find_vqs(struct virtio_device *vdev, struct virtio_vq_config *cfg)
 {
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
 	struct virtqueue *vq;
-	int rc = vp_find_vqs(vdev, nvqs, vqs, callbacks, names, ctx, desc);
+	int rc = vp_find_vqs(vdev, cfg);
 
 	if (rc)
 		return rc;
@@ -739,10 +736,17 @@ static bool vp_get_shm_region(struct virtio_device *vdev,
 static int vp_modern_create_avq(struct virtio_device *vdev)
 {
 	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+	vq_callback_t *callbacks[] = { NULL };
+	struct virtio_vq_config cfg = {};
 	struct virtio_pci_admin_vq *avq;
 	struct virtqueue *vq;
+	const char *names[1];
 	u16 admin_q_num;
 
+	cfg.nvqs = 1;
+	cfg.callbacks = callbacks;
+	cfg.names = names;
+
 	if (!virtio_has_feature(vdev, VIRTIO_F_ADMIN_VQ))
 		return 0;
 
@@ -753,8 +757,10 @@ static int vp_modern_create_avq(struct virtio_device *vdev)
 	avq = &vp_dev->admin_vq;
 	avq->vq_index = vp_modern_avq_index(&vp_dev->mdev);
 	sprintf(avq->name, "avq.%u", avq->vq_index);
-	vq = vp_dev->setup_vq(vp_dev, &vp_dev->admin_vq.info, avq->vq_index, NULL,
-			      avq->name, NULL, VIRTIO_MSI_NO_VECTOR);
+
+	cfg.names[0] = avq->name;
+	vq = vp_dev->setup_vq(vp_dev, &vp_dev->admin_vq.info, avq->vq_index,
+			      &cfg, VIRTIO_MSI_NO_VECTOR);
 	if (IS_ERR(vq)) {
 		dev_err(&vdev->dev, "failed to setup admin virtqueue, err=%ld",
 			PTR_ERR(vq));
diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
index c1a3fbacd463..8cc2eb02c929 100644
--- a/drivers/virtio/virtio_vdpa.c
+++ b/drivers/virtio/virtio_vdpa.c
@@ -142,8 +142,7 @@ static irqreturn_t virtio_vdpa_virtqueue_cb(void *private)
 
 static struct virtqueue *
 virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
-		     void (*callback)(struct virtqueue *vq),
-		     const char *name, bool ctx)
+		     struct virtio_vq_config *cfg)
 {
 	struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
 	struct vdpa_device *vdpa = vd_get_vdpa(vdev);
@@ -161,9 +160,6 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
 	bool may_reduce_num = true;
 	int err;
 
-	if (!name)
-		return NULL;
-
 	if (index >= vdpa->nvqs)
 		return ERR_PTR(-ENOENT);
 
@@ -206,8 +202,12 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
 	else
 		dma_dev = vdpa_get_dma_dev(vdpa);
 	vq = vring_create_virtqueue_dma(index, max_num, align, vdev,
-					true, may_reduce_num, ctx,
-					notify, callback, name, dma_dev);
+					true, may_reduce_num,
+					cfg->ctx ? cfg->ctx[index] : false,
+					notify,
+					cfg->callbacks[index],
+					cfg->names[index],
+					dma_dev);
 	if (!vq) {
 		err = -ENOMEM;
 		goto error_new_virtqueue;
@@ -216,7 +216,7 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
 	vq->num_max = max_num;
 
 	/* Setup virtqueue callback */
-	cb.callback = callback ? virtio_vdpa_virtqueue_cb : NULL;
+	cb.callback = cfg->callbacks[cfg->cfg_idx] ? virtio_vdpa_virtqueue_cb : NULL;
 	cb.private = info;
 	cb.trigger = NULL;
 	ops->set_vq_cb(vdpa, index, &cb);
@@ -356,12 +356,8 @@ create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd)
 	return masks;
 }
 
-static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
-				struct virtqueue *vqs[],
-				vq_callback_t *callbacks[],
-				const char * const names[],
-				const bool *ctx,
-				struct irq_affinity *desc)
+static int virtio_vdpa_find_vqs(struct virtio_device *vdev,
+				struct virtio_vq_config *cfg)
 {
 	struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
 	struct vdpa_device *vdpa = vd_get_vdpa(vdev);
@@ -369,19 +365,19 @@ static int virtio_vdpa_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
 	struct irq_affinity default_affd = { 0 };
 	struct cpumask *masks;
 	struct vdpa_callback cb;
-	bool has_affinity = desc && ops->set_vq_affinity;
+	bool has_affinity = cfg->desc && ops->set_vq_affinity;
+	struct virtqueue **vqs = cfg->vqs;
+	unsigned int nvqs = cfg->nvqs;
 	int i, err, queue_idx = 0;
 
 	if (has_affinity) {
-		masks = create_affinity_masks(nvqs, desc ? desc : &default_affd);
+		masks = create_affinity_masks(nvqs, cfg->desc ? cfg->desc : &default_affd);
 		if (!masks)
 			return -ENOMEM;
 	}
 
 	for (i = 0; i < nvqs; ++i) {
-		vqs[i] = virtio_vdpa_setup_vq(vdev, queue_idx++,
-					      callbacks[i], names[i], ctx ?
-					      ctx[i] : false);
+		vqs[i] = virtio_vdpa_setup_vq(vdev, queue_idx++, cfg);
 		if (IS_ERR(vqs[i])) {
 			err = PTR_ERR(vqs[i]);
 			goto err_setup_vq;
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index d362a29550fa..5fc585e115bc 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -18,6 +18,28 @@ struct virtio_shm_region {
 
 typedef void vq_callback_t(struct virtqueue *);
 
+/**
+ * struct virtio_vq_config - configure for find_vqs()
+ * @nvqs: the number of virtqueues to find
+ * @vqs: on success, includes new virtqueues
+ * @callbacks: array of callbacks, for each virtqueue
+ *	include a NULL entry for vqs that do not need a callback
+ * @names: array of virtqueue names (mainly for debugging)
+ * @ctx: (optional) array of context. If the value of the vq in the array
+ *	is true, the driver can pass ctx to virtio core when adding bufs to
+ *	virtqueue.
+ * @desc: desc for interrupts
+ */
+struct virtio_vq_config {
+	unsigned int nvqs;
+
+	struct virtqueue   **vqs;
+	vq_callback_t      **callbacks;
+	const char         **names;
+	const bool          *ctx;
+	struct irq_affinity *desc;
+};
+
 /**
  * struct virtio_config_ops - operations for configuring a virtio device
  * Note: Do not assume that a transport implements all of the operations
@@ -51,11 +73,7 @@ typedef void vq_callback_t(struct virtqueue *);
  *	parallel with being added/removed.
  * @find_vqs: find virtqueues and instantiate them.
  *	vdev: the virtio_device
- *	nvqs: the number of virtqueues to find
- *	vqs: on success, includes new virtqueues
- *	callbacks: array of callbacks, for each virtqueue
- *		include a NULL entry for vqs that do not need a callback
- *	names: array of virtqueue names (mainly for debugging)
+ *	cfg: the config from the driver
  *	Returns 0 on success or error status
  * @del_vqs: free virtqueues found by find_vqs().
  * @synchronize_cbs: synchronize with the virtqueue callbacks (optional)
@@ -95,6 +113,7 @@ typedef void vq_callback_t(struct virtqueue *);
  * @create_avq: create admin virtqueue resource.
  * @destroy_avq: destroy admin virtqueue resource.
  */
+
 struct virtio_config_ops {
 	void (*get)(struct virtio_device *vdev, unsigned offset,
 		    void *buf, unsigned len);
@@ -104,10 +123,7 @@ struct virtio_config_ops {
 	u8 (*get_status)(struct virtio_device *vdev);
 	void (*set_status)(struct virtio_device *vdev, u8 status);
 	void (*reset)(struct virtio_device *vdev);
-	int (*find_vqs)(struct virtio_device *, unsigned nvqs,
-			struct virtqueue *vqs[], vq_callback_t *callbacks[],
-			const char * const names[], const bool *ctx,
-			struct irq_affinity *desc);
+	int (*find_vqs)(struct virtio_device *vdev, struct virtio_vq_config *cfg);
 	void (*del_vqs)(struct virtio_device *);
 	void (*synchronize_cbs)(struct virtio_device *);
 	u64 (*get_features)(struct virtio_device *vdev);
@@ -216,8 +232,14 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
 	vq_callback_t *callbacks[] = { c };
 	const char *names[] = { n };
 	struct virtqueue *vq;
-	int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL,
-					 NULL);
+	struct virtio_vq_config cfg = {};
+
+	cfg.nvqs = 1;
+	cfg.vqs = &vq;
+	cfg.callbacks = callbacks;
+	cfg.names = names;
+
+	int err = vdev->config->find_vqs(vdev, &cfg);
 	if (err < 0)
 		return ERR_PTR(err);
 	return vq;
@@ -225,21 +247,37 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
 
 static inline
 int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
-			struct virtqueue *vqs[], vq_callback_t *callbacks[],
-			const char * const names[],
-			struct irq_affinity *desc)
+		    struct virtqueue *vqs[], vq_callback_t *callbacks[],
+		    const char * const names[],
+		    struct irq_affinity *desc)
 {
-	return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL, desc);
+	struct virtio_vq_config cfg = {};
+
+	cfg.nvqs = nvqs;
+	cfg.vqs = vqs;
+	cfg.callbacks = callbacks;
+	cfg.names = (const char **)names;
+	cfg.desc = desc;
+
+	return vdev->config->find_vqs(vdev, &cfg);
 }
 
 static inline
 int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs,
 			struct virtqueue *vqs[], vq_callback_t *callbacks[],
-			const char * const names[], const bool *ctx,
+			const char *names[], const bool *ctx,
 			struct irq_affinity *desc)
 {
-	return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, ctx,
-				      desc);
+	struct virtio_vq_config cfg = {};
+
+	cfg.nvqs = nvqs;
+	cfg.vqs = vqs;
+	cfg.callbacks = callbacks;
+	cfg.names = names;
+	cfg.ctx = ctx;
+	cfg.desc = desc;
+
+	return vdev->config->find_vqs(vdev, &cfg);
 }
 
 /**
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH vhost v4 4/6] virtio: vring_create_virtqueue: pass struct instead of multi parameters
  2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
                   ` (2 preceding siblings ...)
  2024-03-21 10:15 ` [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters Xuan Zhuo
@ 2024-03-21 10:15 ` Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 5/6] virtio: vring_new_virtqueue(): " Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 6/6] virtio_ring: simplify the parameters of the funcs related to vring_create/new_virtqueue() Xuan Zhuo
  5 siblings, 0 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

Now, we pass multi parameters to vring_create_virtqueue. These parameters
may from transport or from driver.

vring_create_virtqueue is called by many places.
Every time, we try to add a new parameter, that is difficult.

If parameters from the driver, that should directly be passed to vring.
Then the vring can access the config from driver directly.

If parameters from the transport, we squish the parameters to a
structure. That will be helpful to add new parameter.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 arch/um/drivers/virtio_uml.c       | 14 +++++---
 drivers/s390/virtio/virtio_ccw.c   | 14 ++++----
 drivers/virtio/virtio_mmio.c       | 14 ++++----
 drivers/virtio/virtio_pci_legacy.c | 15 ++++----
 drivers/virtio/virtio_pci_modern.c | 15 ++++----
 drivers/virtio/virtio_ring.c       | 57 ++++++++++++------------------
 drivers/virtio/virtio_vdpa.c       | 21 +++++------
 include/linux/virtio_ring.h        | 51 +++++++++++++-------------
 8 files changed, 101 insertions(+), 100 deletions(-)

diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 140560de2940..02e8538c15a6 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -942,6 +942,7 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev,
 {
 	struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
 	struct platform_device *pdev = vu_dev->pdev;
+	struct vq_transport_config tp_cfg = {};
 	struct virtio_uml_vq_info *info;
 	struct virtqueue *vq;
 	int num = MAX_SUPPORTED_QUEUE_SIZE;
@@ -955,10 +956,15 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev,
 	snprintf(info->name, sizeof(info->name), "%s.%d-%s", pdev->name,
 		 pdev->id, cfg->names[index]);
 
-	vq = vring_create_virtqueue(index, num, PAGE_SIZE, vdev, true, true,
-				    cfg->ctx ? cfg->ctx[index] : false,
-				    vu_notify,
-				    cfg->callbacks[index], info->name);
+	tp_cfg.num = num;
+	tp_cfg.vring_align = PAGE_SIZE;
+	tp_cfg.weak_barriers = true;
+	tp_cfg.may_reduce_num = true;
+	tp_cfg.notify = vu_notify;
+
+	cfg->names[index] = info->name;
+
+	vq = vring_create_virtqueue(vdev, index, &tp_cfg, cfg);
 	if (!vq) {
 		rc = -ENOMEM;
 		goto error_create;
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index 3d6a78bd9c96..912ddaab1835 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -503,6 +503,7 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
 					     struct virtio_vq_config *cfg)
 {
 	struct virtio_ccw_device *vcdev = to_vc_device(vdev);
+	struct vq_transport_config tp_cfg = {};
 	bool (*notify)(struct virtqueue *vq);
 	int err;
 	struct virtqueue *vq = NULL;
@@ -536,13 +537,14 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
 		goto out_err;
 	}
 	may_reduce = vcdev->revision > 0;
-	vq = vring_create_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN,
-				    vdev, true, may_reduce,
-				    cfg->ctx ? cfg->ctx[i] : false,
-				    notify,
-				    cfg->callbacks[i],
-				    cfg->names[i]);
 
+	tp_cfg.num = info->num;
+	tp_cfg.vring_align = KVM_VIRTIO_CCW_RING_ALIGN;
+	tp_cfg.weak_barriers = true;
+	tp_cfg.may_reduce_num = may_reduce;
+	tp_cfg.notify = notify;
+
+	vq = vring_create_virtqueue(vdev, i, &tp_cfg, cfg);
 	if (!vq) {
 		/* For now, we fail if we can't get the requested size. */
 		dev_warn(&vcdev->cdev->dev, "no vq\n");
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 14bb1d862151..4131cd59e856 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -373,6 +373,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
 				     struct virtio_vq_config *cfg)
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+	struct vq_transport_config tp_cfg = {};
 	bool (*notify)(struct virtqueue *vq);
 	struct virtio_mmio_vq_info *info;
 	struct virtqueue *vq;
@@ -408,13 +409,14 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
 		goto error_new_virtqueue;
 	}
 
+	tp_cfg.num = num;
+	tp_cfg.vring_align = VIRTIO_MMIO_VRING_ALIGN;
+	tp_cfg.weak_barriers = true;
+	tp_cfg.may_reduce_num = true;
+	tp_cfg.notify = notify;
+
 	/* Create the vring */
-	vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
-				    true, true,
-				    cfg->ctx ? cfg->ctx[index] : false,
-				    notify,
-				    cfg->callbacks[index],
-				    cfg->names[index]);
+	vq = vring_create_virtqueue(vdev, index, &tp_cfg, cfg);
 	if (!vq) {
 		err = -ENOMEM;
 		goto error_new_virtqueue;
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index a8de653dd7a7..6fe675b2a5e5 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -113,6 +113,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 				  struct virtio_vq_config *cfg,
 				  u16 msix_vec)
 {
+	struct vq_transport_config tp_cfg = {};
 	struct virtqueue *vq;
 	u16 num;
 	int err;
@@ -125,14 +126,14 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 
 	info->msix_vector = msix_vec;
 
+	tp_cfg.num = num;
+	tp_cfg.vring_align = VIRTIO_PCI_VRING_ALIGN;
+	tp_cfg.weak_barriers = true;
+	tp_cfg.may_reduce_num = false;
+	tp_cfg.notify = vp_notify;
+
 	/* create the vring */
-	vq = vring_create_virtqueue(index, num,
-				    VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev,
-				    true, false,
-				    cfg->ctx ? cfg->ctx[index] : false,
-				    vp_notify,
-				    cfg->callbacks[index],
-				    cfg->names[index]);
+	vq = vring_create_virtqueue(&vp_dev->vdev, index, &tp_cfg, cfg);
 	if (!vq)
 		return ERR_PTR(-ENOMEM);
 
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index bcb829ffec64..12130027d0c0 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -535,6 +535,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 {
 
 	struct virtio_pci_modern_device *mdev = &vp_dev->mdev;
+	struct vq_transport_config tp_cfg = {};
 	bool (*notify)(struct virtqueue *vq);
 	struct virtqueue *vq;
 	bool is_avq;
@@ -558,14 +559,14 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 
 	info->msix_vector = msix_vec;
 
+	tp_cfg.num = num;
+	tp_cfg.vring_align = SMP_CACHE_BYTES;
+	tp_cfg.weak_barriers = true;
+	tp_cfg.may_reduce_num = true;
+	tp_cfg.notify = notify;
+
 	/* create the vring */
-	vq = vring_create_virtqueue(index, num,
-				    SMP_CACHE_BYTES, &vp_dev->vdev,
-				    true, true,
-				    cfg->ctx ? cfg->ctx[index] : false,
-				    notify,
-				    cfg->callbacks[index],
-				    cfg->names[index]);
+	vq = vring_create_virtqueue(&vp_dev->vdev, index, &tp_cfg, cfg);
 	if (!vq)
 		return ERR_PTR(-ENOMEM);
 
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 6f7e5010a673..b0e19a84644c 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -2662,43 +2662,32 @@ static struct virtqueue *__vring_new_virtqueue(unsigned int index,
 	return &vq->vq;
 }
 
-struct virtqueue *vring_create_virtqueue(
-	unsigned int index,
-	unsigned int num,
-	unsigned int vring_align,
-	struct virtio_device *vdev,
-	bool weak_barriers,
-	bool may_reduce_num,
-	bool context,
-	bool (*notify)(struct virtqueue *),
-	void (*callback)(struct virtqueue *),
-	const char *name)
+struct virtqueue *vring_create_virtqueue(struct virtio_device *vdev,
+					 unsigned int index,
+					 struct vq_transport_config *tp_cfg,
+					 struct virtio_vq_config *cfg)
 {
+	struct device *dma_dev;
+	unsigned int num;
+	unsigned int vring_align;
+	bool weak_barriers;
+	bool may_reduce_num;
+	bool context;
+	bool (*notify)(struct virtqueue *_);
+	void (*callback)(struct virtqueue *_);
+	const char *name;
 
-	if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED))
-		return vring_create_virtqueue_packed(index, num, vring_align,
-				vdev, weak_barriers, may_reduce_num,
-				context, notify, callback, name, vdev->dev.parent);
+	dma_dev = tp_cfg->dma_dev ? : vdev->dev.parent;
 
-	return vring_create_virtqueue_split(index, num, vring_align,
-			vdev, weak_barriers, may_reduce_num,
-			context, notify, callback, name, vdev->dev.parent);
-}
-EXPORT_SYMBOL_GPL(vring_create_virtqueue);
+	num            = tp_cfg->num;
+	vring_align    = tp_cfg->vring_align;
+	weak_barriers  = tp_cfg->weak_barriers;
+	may_reduce_num = tp_cfg->may_reduce_num;
+	notify         = tp_cfg->notify;
 
-struct virtqueue *vring_create_virtqueue_dma(
-	unsigned int index,
-	unsigned int num,
-	unsigned int vring_align,
-	struct virtio_device *vdev,
-	bool weak_barriers,
-	bool may_reduce_num,
-	bool context,
-	bool (*notify)(struct virtqueue *),
-	void (*callback)(struct virtqueue *),
-	const char *name,
-	struct device *dma_dev)
-{
+	name     = cfg->names[index];
+	callback = cfg->callbacks[index];
+	context  = cfg->ctx ? cfg->ctx[index] : false;
 
 	if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED))
 		return vring_create_virtqueue_packed(index, num, vring_align,
@@ -2709,7 +2698,7 @@ struct virtqueue *vring_create_virtqueue_dma(
 			vdev, weak_barriers, may_reduce_num,
 			context, notify, callback, name, dma_dev);
 }
-EXPORT_SYMBOL_GPL(vring_create_virtqueue_dma);
+EXPORT_SYMBOL_GPL(vring_create_virtqueue);
 
 /**
  * virtqueue_resize - resize the vring of vq
diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
index 8cc2eb02c929..765d48374c8d 100644
--- a/drivers/virtio/virtio_vdpa.c
+++ b/drivers/virtio/virtio_vdpa.c
@@ -146,8 +146,8 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
 {
 	struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
 	struct vdpa_device *vdpa = vd_get_vdpa(vdev);
-	struct device *dma_dev;
 	const struct vdpa_config_ops *ops = vdpa->config;
+	struct vq_transport_config tp_cfg = {};
 	struct virtio_vdpa_vq_info *info;
 	bool (*notify)(struct virtqueue *vq) = virtio_vdpa_notify;
 	struct vdpa_callback cb;
@@ -198,16 +198,17 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
 	align = ops->get_vq_align(vdpa);
 
 	if (ops->get_vq_dma_dev)
-		dma_dev = ops->get_vq_dma_dev(vdpa, index);
+		tp_cfg.dma_dev = ops->get_vq_dma_dev(vdpa, index);
 	else
-		dma_dev = vdpa_get_dma_dev(vdpa);
-	vq = vring_create_virtqueue_dma(index, max_num, align, vdev,
-					true, may_reduce_num,
-					cfg->ctx ? cfg->ctx[index] : false,
-					notify,
-					cfg->callbacks[index],
-					cfg->names[index],
-					dma_dev);
+		tp_cfg.dma_dev = vdpa_get_dma_dev(vdpa);
+
+	tp_cfg.num = max_num;
+	tp_cfg.vring_align = align;
+	tp_cfg.weak_barriers = true;
+	tp_cfg.may_reduce_num = may_reduce_num;
+	tp_cfg.notify = notify;
+
+	vq = vring_create_virtqueue(vdev, index, &tp_cfg, cfg);
 	if (!vq) {
 		err = -ENOMEM;
 		goto error_new_virtqueue;
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index 9b33df741b63..0a81f7f025ce 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -5,6 +5,7 @@
 #include <asm/barrier.h>
 #include <linux/irqreturn.h>
 #include <uapi/linux/virtio_ring.h>
+#include <linux/virtio_config.h>
 
 /*
  * Barriers in virtio are tricky.  Non-SMP virtio guests can't assume
@@ -60,38 +61,36 @@ struct virtio_device;
 struct virtqueue;
 struct device;
 
+/**
+ * struct vq_transport_config - Configuration for creating a new virtqueue (vq)
+ * @num: Number of descriptors in this virtqueue.
+ * @vring_align: Alignment size of this virtqueue's ring.
+ * @weak_barriers: Memory barrier strategy used within virtio_[rw]mb() to
+ *	enforce ordering of memory operations.
+ * @may_reduce_num: Indicates whether the number of descriptors can be reduced
+ *	if vring allocation fails.
+ * @notify: Callback function used to notify the device of certain events.
+ * @dma_dev: DMA device associated with this virtqueue, used by the DMA API.
+ */
+struct vq_transport_config {
+	unsigned int num;
+	unsigned int vring_align;
+	bool weak_barriers;
+	bool may_reduce_num;
+	bool (*notify)(struct virtqueue *vq);
+	struct device *dma_dev;
+};
+
 /*
  * Creates a virtqueue and allocates the descriptor ring.  If
  * may_reduce_num is set, then this may allocate a smaller ring than
  * expected.  The caller should query virtqueue_get_vring_size to learn
  * the actual size of the ring.
  */
-struct virtqueue *vring_create_virtqueue(unsigned int index,
-					 unsigned int num,
-					 unsigned int vring_align,
-					 struct virtio_device *vdev,
-					 bool weak_barriers,
-					 bool may_reduce_num,
-					 bool ctx,
-					 bool (*notify)(struct virtqueue *vq),
-					 void (*callback)(struct virtqueue *vq),
-					 const char *name);
-
-/*
- * Creates a virtqueue and allocates the descriptor ring with per
- * virtqueue DMA device.
- */
-struct virtqueue *vring_create_virtqueue_dma(unsigned int index,
-					     unsigned int num,
-					     unsigned int vring_align,
-					     struct virtio_device *vdev,
-					     bool weak_barriers,
-					     bool may_reduce_num,
-					     bool ctx,
-					     bool (*notify)(struct virtqueue *vq),
-					     void (*callback)(struct virtqueue *vq),
-					     const char *name,
-					     struct device *dma_dev);
+struct virtqueue *vring_create_virtqueue(struct virtio_device *vdev,
+					 unsigned int index,
+					 struct vq_transport_config *tp_cfg,
+					 struct virtio_vq_config *cfg);
 
 /*
  * Creates a virtqueue with a standard layout but a caller-allocated
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH vhost v4 5/6] virtio: vring_new_virtqueue(): pass struct instead of multi parameters
  2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
                   ` (3 preceding siblings ...)
  2024-03-21 10:15 ` [PATCH vhost v4 4/6] virtio: vring_create_virtqueue: " Xuan Zhuo
@ 2024-03-21 10:15 ` Xuan Zhuo
  2024-03-21 10:15 ` [PATCH vhost v4 6/6] virtio_ring: simplify the parameters of the funcs related to vring_create/new_virtqueue() Xuan Zhuo
  5 siblings, 0 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

Now, we pass multi parameters to vring_new_virtqueue. These parameters
may from transport or from driver.

vring_new_virtqueue is called by many places.
Every time, we try to add a new parameter, that is difficult.

If parameters from the driver, that should directly be passed to vring.
Then the vring can access the config from driver directly.

If parameters from the transport, we squish the parameters to a
structure. That will be helpful to add new parameter.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/platform/mellanox/mlxbf-tmfifo.c | 12 ++++---
 drivers/remoteproc/remoteproc_virtio.c   | 11 ++++---
 drivers/virtio/virtio_ring.c             | 29 +++++++++++-----
 include/linux/virtio_ring.h              | 42 +++++++++++++++++++-----
 tools/virtio/virtio_test.c               |  4 +--
 tools/virtio/vringh_test.c               | 28 ++++++++--------
 6 files changed, 84 insertions(+), 42 deletions(-)

diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
index 10e74eb95d31..8847fb3156e7 100644
--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -1059,6 +1059,7 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
 					struct virtio_vq_config *cfg)
 {
 	struct mlxbf_tmfifo_vdev *tm_vdev = mlxbf_vdev_to_tmfifo(vdev);
+	struct vq_transport_config tp_cfg = {};
 	struct virtqueue **vqs = cfg->vqs;
 	struct mlxbf_tmfifo_vring *vring;
 	unsigned int nvqs = cfg->nvqs;
@@ -1074,10 +1075,13 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev,
 		/* zero vring */
 		size = vring_size(vring->num, vring->align);
 		memset(vring->va, 0, size);
-		vq = vring_new_virtqueue(i, vring->num, vring->align, vdev,
-					 false, false, vring->va,
-					 mlxbf_tmfifo_virtio_notify,
-					 cfg->callbacks[i], cfg->names[i]);
+
+		tp_cfg.num = vring->num;
+		tp_cfg.vring_align = vring->align;
+		tp_cfg.weak_barriers = false;
+		tp_cfg.notify = mlxbf_tmfifo_virtio_notify;
+
+		vq = vring_new_virtqueue(vdev, i, vring->va, &tp_cfg, cfg);
 		if (!vq) {
 			dev_err(&vdev->dev, "vring_new_virtqueue failed\n");
 			ret = -ENOMEM;
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 3da1529e445d..a2e3b423ccfb 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -106,6 +106,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
 {
 	struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
 	struct rproc *rproc = vdev_to_rproc(vdev);
+	struct vq_transport_config tp_cfg;
 	struct device *dev = &rproc->dev;
 	struct rproc_mem_entry *mem;
 	struct rproc_vring *rvring;
@@ -135,14 +136,16 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
 	dev_dbg(dev, "vring%d: va %pK qsz %d notifyid %d\n",
 		id, addr, num, rvring->notifyid);
 
+	tp_cfg.num = num;
+	tp_cfg.vring_align = rvring->align;
+	tp_cfg.weak_barriers = false;
+	tp_cfg.notify = rproc_virtio_notify;
+
 	/*
 	 * Create the new vq, and tell virtio we're not interested in
 	 * the 'weak' smp barriers, since we're talking with a real device.
 	 */
-	vq = vring_new_virtqueue(id, num, rvring->align, vdev, false,
-				 cfg->ctx ? cfg->ctx[id] : false,
-				 addr, rproc_virtio_notify, cfg->callbacks[id],
-				 cfg->names[id]);
+	vq = vring_new_virtqueue(vdev, id, addr, &tp_cfg, cfg);
 	if (!vq) {
 		dev_err(dev, "vring_new_virtqueue %s failed\n", cfg->names[id]);
 		rproc_free_vring(rvring);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b0e19a84644c..20e5e4779f36 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -2835,18 +2835,29 @@ int virtqueue_reset(struct virtqueue *_vq,
 EXPORT_SYMBOL_GPL(virtqueue_reset);
 
 /* Only available for split ring */
-struct virtqueue *vring_new_virtqueue(unsigned int index,
-				      unsigned int num,
-				      unsigned int vring_align,
-				      struct virtio_device *vdev,
-				      bool weak_barriers,
-				      bool context,
+struct virtqueue *vring_new_virtqueue(struct virtio_device *vdev,
+				      unsigned int index,
 				      void *pages,
-				      bool (*notify)(struct virtqueue *vq),
-				      void (*callback)(struct virtqueue *vq),
-				      const char *name)
+				      struct vq_transport_config *tp_cfg,
+				      struct virtio_vq_config *cfg)
 {
 	struct vring_virtqueue_split vring_split = {};
+	unsigned int num;
+	unsigned int vring_align;
+	bool weak_barriers;
+	bool context;
+	bool (*notify)(struct virtqueue *_);
+	void (*callback)(struct virtqueue *_);
+	const char *name;
+
+	num            = tp_cfg->num;
+	vring_align    = tp_cfg->vring_align;
+	weak_barriers  = tp_cfg->weak_barriers;
+	notify         = tp_cfg->notify;
+
+	name     = cfg->names[index];
+	callback = cfg->callbacks[index];
+	context  = cfg->ctx ? cfg->ctx[index] : false;
 
 	if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED))
 		return NULL;
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index 0a81f7f025ce..ed005dc65cc0 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -96,16 +96,40 @@ struct virtqueue *vring_create_virtqueue(struct virtio_device *vdev,
  * Creates a virtqueue with a standard layout but a caller-allocated
  * ring.
  */
-struct virtqueue *vring_new_virtqueue(unsigned int index,
-				      unsigned int num,
-				      unsigned int vring_align,
-				      struct virtio_device *vdev,
-				      bool weak_barriers,
-				      bool ctx,
+struct virtqueue *vring_new_virtqueue(struct virtio_device *vdev,
+				      unsigned int index,
 				      void *pages,
-				      bool (*notify)(struct virtqueue *vq),
-				      void (*callback)(struct virtqueue *vq),
-				      const char *name);
+				      struct vq_transport_config *tp_cfg,
+				      struct virtio_vq_config *cfg);
+
+static inline struct virtqueue *vring_new_virtqueue_one(unsigned int index,
+							unsigned int num,
+							unsigned int vring_align,
+							struct virtio_device *vdev,
+							bool weak_barriers,
+							bool context,
+							void *pages,
+							bool (*notify)(struct virtqueue *vq),
+							void (*callback)(struct virtqueue *vq),
+							const char *name)
+{
+	struct vq_transport_config tp_cfg = {};
+	struct virtio_vq_config cfg = {};
+	vq_callback_t *callbacks[] = { callback };
+	const char *names[] = { name };
+
+	tp_cfg.num = num;
+	tp_cfg.vring_align = vring_align;
+	tp_cfg.weak_barriers = weak_barriers;
+	tp_cfg.notify = notify;
+
+	cfg.nvqs = 1;
+	cfg.callbacks = callbacks;
+	cfg.names = names;
+	cfg.ctx = &context;
+
+	return vring_new_virtqueue(vdev, index, pages, &tp_cfg, &cfg);
+}
 
 /*
  * Destroys a virtqueue.  If created with vring_create_virtqueue, this
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
index 028f54e6854a..e41300d71d5e 100644
--- a/tools/virtio/virtio_test.c
+++ b/tools/virtio/virtio_test.c
@@ -102,8 +102,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev)
 
 	memset(info->ring, 0, vring_size(num, 4096));
 	vring_init(&info->vring, num, info->ring, 4096);
-	info->vq = vring_new_virtqueue(info->idx, num, 4096, vdev, true, false,
-				       info->ring, vq_notify, vq_callback, "test");
+	info->vq = vring_new_virtqueue_one(info->idx, num, 4096, vdev, true, false,
+					   info->ring, vq_notify, vq_callback, "test");
 	assert(info->vq);
 	info->vq->priv = info;
 }
diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c
index 98ff808d6f0c..040689111584 100644
--- a/tools/virtio/vringh_test.c
+++ b/tools/virtio/vringh_test.c
@@ -316,11 +316,11 @@ static int parallel_test(u64 features,
 		if (sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set))
 			err(1, "Could not set affinity to cpu %u", first_cpu);
 
-		vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &gvdev.vdev, true,
-					 false, guest_map,
-					 fast_vringh ? no_notify_host
-					 : parallel_notify_host,
-					 never_callback_guest, "guest vq");
+		vq = vring_new_virtqueue_one(0, RINGSIZE, ALIGN, &gvdev.vdev, true,
+					     false, guest_map,
+					     fast_vringh ? no_notify_host
+					     : parallel_notify_host,
+					     never_callback_guest, "guest vq");
 
 		/* Don't kfree indirects. */
 		__kfree_ignore_start = indirects;
@@ -485,10 +485,10 @@ int main(int argc, char *argv[])
 	memset(__user_addr_min, 0, vring_size(RINGSIZE, ALIGN));
 
 	/* Set up guest side. */
-	vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, false,
-				 __user_addr_min,
-				 never_notify_host, never_callback_guest,
-				 "guest vq");
+	vq = vring_new_virtqueue_one(0, RINGSIZE, ALIGN, &vdev, true, false,
+				     __user_addr_min,
+				     never_notify_host, never_callback_guest,
+				     "guest vq");
 
 	/* Set up host side. */
 	vring_init(&vrh.vring, RINGSIZE, __user_addr_min, ALIGN);
@@ -668,11 +668,11 @@ int main(int argc, char *argv[])
 
 		/* Force creation of direct, which we modify. */
 		__virtio_clear_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC);
-		vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true,
-					 false, __user_addr_min,
-					 never_notify_host,
-					 never_callback_guest,
-					 "guest vq");
+		vq = vring_new_virtqueue_one(0, RINGSIZE, ALIGN, &vdev, true,
+					     false, __user_addr_min,
+					     never_notify_host,
+					     never_callback_guest,
+					     "guest vq");
 
 		sg_init_table(guest_sg, 4);
 		sg_set_buf(&guest_sg[0], d, sizeof(*d)*2);
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH vhost v4 6/6] virtio_ring: simplify the parameters of the funcs related to vring_create/new_virtqueue()
  2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
                   ` (4 preceding siblings ...)
  2024-03-21 10:15 ` [PATCH vhost v4 5/6] virtio: vring_new_virtqueue(): " Xuan Zhuo
@ 2024-03-21 10:15 ` Xuan Zhuo
  5 siblings, 0 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-21 10:15 UTC (permalink / raw)
  To: virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, Xuan Zhuo, linux-um,
	platform-driver-x86, linux-remoteproc, linux-s390, kvm

As the refactor of find_vqs()/vring_new_virtqueue()/vring_create_virtqueue
the struct cfg/tp_cfg are passed to vring.

This patch refactors the vring by these structures. This can simplify
the code.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/virtio/virtio_ring.c | 157 +++++++++++------------------------
 1 file changed, 50 insertions(+), 107 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 20e5e4779f36..70de1a9a81a3 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -223,15 +223,11 @@ struct vring_virtqueue {
 #endif
 };
 
-static struct virtqueue *__vring_new_virtqueue(unsigned int index,
+static struct virtqueue *__vring_new_virtqueue(struct virtio_device *vdev,
+					       unsigned int index,
 					       struct vring_virtqueue_split *vring_split,
-					       struct virtio_device *vdev,
-					       bool weak_barriers,
-					       bool context,
-					       bool (*notify)(struct virtqueue *),
-					       void (*callback)(struct virtqueue *),
-					       const char *name,
-					       struct device *dma_dev);
+					       struct vq_transport_config *tp_cfg,
+					       struct virtio_vq_config *cfg);
 static struct vring_desc_extra *vring_alloc_desc_extra(unsigned int num);
 static void vring_free(struct virtqueue *_vq);
 
@@ -240,6 +236,8 @@ static void vring_free(struct virtqueue *_vq);
  */
 
 #define to_vvq(_vq) container_of_const(_vq, struct vring_virtqueue, vq)
+#define cfg_vq_val(cfg, vq, key) (cfg->key[vq->vq.index])
+#define cfg_vq_get(cfg, vq, key) (cfg->key ? cfg_vq_val(cfg, vq, key) : false)
 
 static bool virtqueue_use_indirect(const struct vring_virtqueue *vq,
 				   unsigned int total_sg)
@@ -1138,32 +1136,28 @@ static int vring_alloc_queue_split(struct vring_virtqueue_split *vring_split,
 	return 0;
 }
 
-static struct virtqueue *vring_create_virtqueue_split(
-	unsigned int index,
-	unsigned int num,
-	unsigned int vring_align,
-	struct virtio_device *vdev,
-	bool weak_barriers,
-	bool may_reduce_num,
-	bool context,
-	bool (*notify)(struct virtqueue *),
-	void (*callback)(struct virtqueue *),
-	const char *name,
-	struct device *dma_dev)
+static struct virtqueue *vring_create_virtqueue_split(struct virtio_device *vdev,
+						      unsigned int index,
+						      struct vq_transport_config *tp_cfg,
+						      struct virtio_vq_config *cfg)
 {
 	struct vring_virtqueue_split vring_split = {};
 	struct virtqueue *vq;
 	int err;
 
-	err = vring_alloc_queue_split(&vring_split, vdev, num, vring_align,
-				      may_reduce_num, dma_dev);
+	tp_cfg->dma_dev = tp_cfg->dma_dev ? : vdev->dev.parent;
+
+	err = vring_alloc_queue_split(&vring_split, vdev,
+				      tp_cfg->num,
+				      tp_cfg->vring_align,
+				      tp_cfg->may_reduce_num,
+				      tp_cfg->dma_dev);
 	if (err)
 		return NULL;
 
-	vq = __vring_new_virtqueue(index, &vring_split, vdev, weak_barriers,
-				   context, notify, callback, name, dma_dev);
+	vq = __vring_new_virtqueue(vdev, index, &vring_split, tp_cfg, cfg);
 	if (!vq) {
-		vring_free_split(&vring_split, vdev, dma_dev);
+		vring_free_split(&vring_split, vdev, tp_cfg->dma_dev);
 		return NULL;
 	}
 
@@ -2050,38 +2044,33 @@ static void virtqueue_reinit_packed(struct vring_virtqueue *vq)
 	virtqueue_vring_init_packed(&vq->packed, !!vq->vq.callback);
 }
 
-static struct virtqueue *vring_create_virtqueue_packed(
-	unsigned int index,
-	unsigned int num,
-	unsigned int vring_align,
-	struct virtio_device *vdev,
-	bool weak_barriers,
-	bool may_reduce_num,
-	bool context,
-	bool (*notify)(struct virtqueue *),
-	void (*callback)(struct virtqueue *),
-	const char *name,
-	struct device *dma_dev)
+static struct virtqueue *vring_create_virtqueue_packed(struct virtio_device *vdev,
+						       unsigned int index,
+						       struct vq_transport_config *tp_cfg,
+						       struct virtio_vq_config *cfg)
 {
 	struct vring_virtqueue_packed vring_packed = {};
 	struct vring_virtqueue *vq;
+	struct device *dma_dev;
 	int err;
 
-	if (vring_alloc_queue_packed(&vring_packed, vdev, num, dma_dev))
+	dma_dev = tp_cfg->dma_dev ? : vdev->dev.parent;
+
+	if (vring_alloc_queue_packed(&vring_packed, vdev, tp_cfg->num, dma_dev))
 		goto err_ring;
 
 	vq = kmalloc(sizeof(*vq), GFP_KERNEL);
 	if (!vq)
 		goto err_vq;
 
-	vq->vq.callback = callback;
+	vq->vq.callback = cfg_vq_val(cfg, vq, callbacks);
 	vq->vq.vdev = vdev;
-	vq->vq.name = name;
+	vq->vq.name = cfg_vq_val(cfg, vq, names);
 	vq->vq.index = index;
 	vq->vq.reset = false;
 	vq->we_own_ring = true;
-	vq->notify = notify;
-	vq->weak_barriers = weak_barriers;
+	vq->notify = tp_cfg->notify;
+	vq->weak_barriers = tp_cfg->weak_barriers;
 #ifdef CONFIG_VIRTIO_HARDEN_NOTIFICATION
 	vq->broken = true;
 #else
@@ -2094,7 +2083,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
 	vq->do_unmap = vq->use_dma_api;
 
 	vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC) &&
-		!context;
+		!cfg_vq_get(cfg, vq, ctx);
 	vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
 
 	if (virtio_has_feature(vdev, VIRTIO_F_ORDER_PLATFORM))
@@ -2104,9 +2093,9 @@ static struct virtqueue *vring_create_virtqueue_packed(
 	if (err)
 		goto err_state_extra;
 
-	virtqueue_vring_init_packed(&vring_packed, !!callback);
+	virtqueue_vring_init_packed(&vring_packed, !!cfg_vq_val(cfg, vq, callbacks));
 
-	virtqueue_init(vq, num);
+	virtqueue_init(vq, tp_cfg->num);
 	virtqueue_vring_attach_packed(vq, &vring_packed);
 
 	spin_lock(&vdev->vqs_list_lock);
@@ -2599,15 +2588,11 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
 EXPORT_SYMBOL_GPL(vring_interrupt);
 
 /* Only available for split ring */
-static struct virtqueue *__vring_new_virtqueue(unsigned int index,
+static struct virtqueue *__vring_new_virtqueue(struct virtio_device *vdev,
+					       unsigned int index,
 					       struct vring_virtqueue_split *vring_split,
-					       struct virtio_device *vdev,
-					       bool weak_barriers,
-					       bool context,
-					       bool (*notify)(struct virtqueue *),
-					       void (*callback)(struct virtqueue *),
-					       const char *name,
-					       struct device *dma_dev)
+					       struct vq_transport_config *tp_cfg,
+					       struct virtio_vq_config *cfg)
 {
 	struct vring_virtqueue *vq;
 	int err;
@@ -2620,26 +2605,26 @@ static struct virtqueue *__vring_new_virtqueue(unsigned int index,
 		return NULL;
 
 	vq->packed_ring = false;
-	vq->vq.callback = callback;
+	vq->vq.callback = cfg_vq_val(cfg, vq, callbacks);
 	vq->vq.vdev = vdev;
-	vq->vq.name = name;
+	vq->vq.name = cfg_vq_val(cfg, vq, names);
 	vq->vq.index = index;
 	vq->vq.reset = false;
 	vq->we_own_ring = false;
-	vq->notify = notify;
-	vq->weak_barriers = weak_barriers;
+	vq->notify = tp_cfg->notify;
+	vq->weak_barriers = tp_cfg->weak_barriers;
 #ifdef CONFIG_VIRTIO_HARDEN_NOTIFICATION
 	vq->broken = true;
 #else
 	vq->broken = false;
 #endif
-	vq->dma_dev = dma_dev;
+	vq->dma_dev = tp_cfg->dma_dev;
 	vq->use_dma_api = vring_use_dma_api(vdev);
 	vq->premapped = false;
 	vq->do_unmap = vq->use_dma_api;
 
 	vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC) &&
-		!context;
+		!cfg_vq_get(cfg, vq, ctx);
 	vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
 
 	if (virtio_has_feature(vdev, VIRTIO_F_ORDER_PLATFORM))
@@ -2667,36 +2652,10 @@ struct virtqueue *vring_create_virtqueue(struct virtio_device *vdev,
 					 struct vq_transport_config *tp_cfg,
 					 struct virtio_vq_config *cfg)
 {
-	struct device *dma_dev;
-	unsigned int num;
-	unsigned int vring_align;
-	bool weak_barriers;
-	bool may_reduce_num;
-	bool context;
-	bool (*notify)(struct virtqueue *_);
-	void (*callback)(struct virtqueue *_);
-	const char *name;
-
-	dma_dev = tp_cfg->dma_dev ? : vdev->dev.parent;
-
-	num            = tp_cfg->num;
-	vring_align    = tp_cfg->vring_align;
-	weak_barriers  = tp_cfg->weak_barriers;
-	may_reduce_num = tp_cfg->may_reduce_num;
-	notify         = tp_cfg->notify;
-
-	name     = cfg->names[index];
-	callback = cfg->callbacks[index];
-	context  = cfg->ctx ? cfg->ctx[index] : false;
-
 	if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED))
-		return vring_create_virtqueue_packed(index, num, vring_align,
-				vdev, weak_barriers, may_reduce_num,
-				context, notify, callback, name, dma_dev);
+		return vring_create_virtqueue_packed(vdev, index, tp_cfg, cfg);
 
-	return vring_create_virtqueue_split(index, num, vring_align,
-			vdev, weak_barriers, may_reduce_num,
-			context, notify, callback, name, dma_dev);
+	return vring_create_virtqueue_split(vdev, index, tp_cfg, cfg);
 }
 EXPORT_SYMBOL_GPL(vring_create_virtqueue);
 
@@ -2842,30 +2801,14 @@ struct virtqueue *vring_new_virtqueue(struct virtio_device *vdev,
 				      struct virtio_vq_config *cfg)
 {
 	struct vring_virtqueue_split vring_split = {};
-	unsigned int num;
-	unsigned int vring_align;
-	bool weak_barriers;
-	bool context;
-	bool (*notify)(struct virtqueue *_);
-	void (*callback)(struct virtqueue *_);
-	const char *name;
-
-	num            = tp_cfg->num;
-	vring_align    = tp_cfg->vring_align;
-	weak_barriers  = tp_cfg->weak_barriers;
-	notify         = tp_cfg->notify;
-
-	name     = cfg->names[index];
-	callback = cfg->callbacks[index];
-	context  = cfg->ctx ? cfg->ctx[index] : false;
 
 	if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED))
 		return NULL;
 
-	vring_init(&vring_split.vring, num, pages, vring_align);
-	return __vring_new_virtqueue(index, &vring_split, vdev, weak_barriers,
-				     context, notify, callback, name,
-				     vdev->dev.parent);
+	tp_cfg->dma_dev = vdev->dev.parent;
+
+	vring_init(&vring_split.vring, tp_cfg->num, pages, tp_cfg->vring_align);
+	return __vring_new_virtqueue(vdev, index, &vring_split, tp_cfg, cfg);
 }
 EXPORT_SYMBOL_GPL(vring_new_virtqueue);
 
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-21 10:15 ` [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null Xuan Zhuo
@ 2024-03-22 11:56   ` David Hildenbrand
  2024-03-25  6:03     ` Xuan Zhuo
  2024-03-22 19:16   ` Daniel Verkamp
  1 sibling, 1 reply; 19+ messages in thread
From: David Hildenbrand @ 2024-03-22 11:56 UTC (permalink / raw)
  To: Xuan Zhuo, virtualization
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	Jason Wang, linux-um, platform-driver-x86, linux-remoteproc,
	linux-s390, kvm

On 21.03.24 11:15, Xuan Zhuo wrote:
> Currently, the init_vqs function within the virtio_balloon driver relies
> on the condition that certain names array entries are null in order to
> skip the initialization of some virtual queues (vqs). This behavior is
> unique to this part of the codebase. In an upcoming commit, we plan to
> eliminate this dependency by removing the function entirely. Therefore,
> with this change, we are ensuring that the virtio_balloon no longer
> depends on the aforementioned function.
> 
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>   drivers/virtio/virtio_balloon.c | 41 +++++++++++++++------------------
>   1 file changed, 19 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
> index 1f5b3dd31fcf..becc12a05407 100644
> --- a/drivers/virtio/virtio_balloon.c
> +++ b/drivers/virtio/virtio_balloon.c
> @@ -531,49 +531,46 @@ static int init_vqs(struct virtio_balloon *vb)
>   	struct virtqueue *vqs[VIRTIO_BALLOON_VQ_MAX];
>   	vq_callback_t *callbacks[VIRTIO_BALLOON_VQ_MAX];
>   	const char *names[VIRTIO_BALLOON_VQ_MAX];
> -	int err;
> +	int err, nvqs, idx;
>   
> -	/*
> -	 * Inflateq and deflateq are used unconditionally. The names[]
> -	 * will be NULL if the related feature is not enabled, which will
> -	 * cause no allocation for the corresponding virtqueue in find_vqs.
> -	 */
>   	callbacks[VIRTIO_BALLOON_VQ_INFLATE] = balloon_ack;
>   	names[VIRTIO_BALLOON_VQ_INFLATE] = "inflate";
>   	callbacks[VIRTIO_BALLOON_VQ_DEFLATE] = balloon_ack;
>   	names[VIRTIO_BALLOON_VQ_DEFLATE] = "deflate";

I'd remove the static dependencies here completely and do it
consistently:

nvqs = 0;

callbacks[nvqs] = balloon_ack;
names[nvqs++] = "inflate";
callbacks[nvqs] = balloon_ack;
names[nvqs++] = "deflate";


> -	callbacks[VIRTIO_BALLOON_VQ_STATS] = NULL;
> -	names[VIRTIO_BALLOON_VQ_STATS] = NULL;
> -	callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
> -	names[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
> -	names[VIRTIO_BALLOON_VQ_REPORTING] = NULL;
> +
> +	nvqs = VIRTIO_BALLOON_VQ_DEFLATE + 1;
>   
>   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
> -		names[VIRTIO_BALLOON_VQ_STATS] = "stats";
> -		callbacks[VIRTIO_BALLOON_VQ_STATS] = stats_request;
> +		names[nvqs] = "stats";
> +		callbacks[nvqs] = stats_request;
> +		++nvqs;

callbacks[nvqs++] = stats_request;

If you prefer to keep it separate, "nvqs++" please.

... same here:

idx = 0;
vb->inflate_vq = vqs[idx++];
vb->deflate_vq = vqs[idx++];

...

>   
>   	vb->inflate_vq = vqs[VIRTIO_BALLOON_VQ_INFLATE];
>   	vb->deflate_vq = vqs[VIRTIO_BALLOON_VQ_DEFLATE];
> +
> +	idx = VIRTIO_BALLOON_VQ_DEFLATE + 1;
> +
>   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
>   		struct scatterlist sg;
>   		unsigned int num_stats;
> -		vb->stats_vq = vqs[VIRTIO_BALLOON_VQ_STATS];
> +		vb->stats_vq = vqs[idx++];
>   
>   		/*
>   		 * Prime this virtqueue with one buffer so the hypervisor can
> @@ -593,10 +590,10 @@ static int init_vqs(struct virtio_balloon *vb)
>   	}
>   
>   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
> -		vb->free_page_vq = vqs[VIRTIO_BALLOON_VQ_FREE_PAGE];
> +		vb->free_page_vq = vqs[idx++];
>   
>   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING))
> -		vb->reporting_vq = vqs[VIRTIO_BALLOON_VQ_REPORTING];
> +		vb->reporting_vq = vqs[idx++];
>   

Apart from that LGTM

-- 
Cheers,

David / dhildenb


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters
  2024-03-21 10:15 ` [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters Xuan Zhuo
@ 2024-03-22 14:10   ` kernel test robot
  2024-03-23  0:29   ` kernel test robot
  1 sibling, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-03-22 14:10 UTC (permalink / raw)
  To: Xuan Zhuo; +Cc: oe-kbuild-all

Hi Xuan,

kernel test robot noticed the following build errors:

[auto build test ERROR on remoteproc/rproc-next]
[also build test ERROR on v6.8]
[cannot apply to s390/features linus/master uml/next uml/fixes next-20240322]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Xuan-Zhuo/virtio_balloon-remove-the-dependence-where-names-is-null/20240321-182217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
patch link:    https://lore.kernel.org/r/20240321101532.59272-4-xuanzhuo%40linux.alibaba.com
patch subject: [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20240322/202403222227.Sdp23Lcb-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240322/202403222227.Sdp23Lcb-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403222227.Sdp23Lcb-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/virtio/virtio_vdpa.c: In function 'virtio_vdpa_setup_vq':
>> drivers/virtio/virtio_vdpa.c:216:41: error: 'struct virtio_vq_config' has no member named 'cfg_idx'
     216 |         cb.callback = cfg->callbacks[cfg->cfg_idx] ? virtio_vdpa_virtqueue_cb : NULL;
         |                                         ^~


vim +216 drivers/virtio/virtio_vdpa.c

   142	
   143	static struct virtqueue *
   144	virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
   145			     struct virtio_vq_config *cfg)
   146	{
   147		struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
   148		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
   149		struct device *dma_dev;
   150		const struct vdpa_config_ops *ops = vdpa->config;
   151		struct virtio_vdpa_vq_info *info;
   152		bool (*notify)(struct virtqueue *vq) = virtio_vdpa_notify;
   153		struct vdpa_callback cb;
   154		struct virtqueue *vq;
   155		u64 desc_addr, driver_addr, device_addr;
   156		/* Assume split virtqueue, switch to packed if necessary */
   157		struct vdpa_vq_state state = {0};
   158		unsigned long flags;
   159		u32 align, max_num, min_num = 1;
   160		bool may_reduce_num = true;
   161		int err;
   162	
   163		if (index >= vdpa->nvqs)
   164			return ERR_PTR(-ENOENT);
   165	
   166		/* We cannot accept VIRTIO_F_NOTIFICATION_DATA without kick_vq_with_data */
   167		if (__virtio_test_bit(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
   168			if (ops->kick_vq_with_data)
   169				notify = virtio_vdpa_notify_with_data;
   170			else
   171				__virtio_clear_bit(vdev, VIRTIO_F_NOTIFICATION_DATA);
   172		}
   173	
   174		/* Queue shouldn't already be set up. */
   175		if (ops->get_vq_ready(vdpa, index))
   176			return ERR_PTR(-ENOENT);
   177	
   178		/* Allocate and fill out our active queue description */
   179		info = kmalloc(sizeof(*info), GFP_KERNEL);
   180		if (!info)
   181			return ERR_PTR(-ENOMEM);
   182	
   183		max_num = ops->get_vq_num_max(vdpa);
   184		if (max_num == 0) {
   185			err = -ENOENT;
   186			goto error_new_virtqueue;
   187		}
   188	
   189		if (ops->get_vq_num_min)
   190			min_num = ops->get_vq_num_min(vdpa);
   191	
   192		may_reduce_num = (max_num == min_num) ? false : true;
   193	
   194		/* Create the vring */
   195		align = ops->get_vq_align(vdpa);
   196	
   197		if (ops->get_vq_dma_dev)
   198			dma_dev = ops->get_vq_dma_dev(vdpa, index);
   199		else
   200			dma_dev = vdpa_get_dma_dev(vdpa);
   201		vq = vring_create_virtqueue_dma(index, max_num, align, vdev,
   202						true, may_reduce_num,
   203						cfg->ctx ? cfg->ctx[index] : false,
   204						notify,
   205						cfg->callbacks[index],
   206						cfg->names[index],
   207						dma_dev);
   208		if (!vq) {
   209			err = -ENOMEM;
   210			goto error_new_virtqueue;
   211		}
   212	
   213		vq->num_max = max_num;
   214	
   215		/* Setup virtqueue callback */
 > 216		cb.callback = cfg->callbacks[cfg->cfg_idx] ? virtio_vdpa_virtqueue_cb : NULL;
   217		cb.private = info;
   218		cb.trigger = NULL;
   219		ops->set_vq_cb(vdpa, index, &cb);
   220		ops->set_vq_num(vdpa, index, virtqueue_get_vring_size(vq));
   221	
   222		desc_addr = virtqueue_get_desc_addr(vq);
   223		driver_addr = virtqueue_get_avail_addr(vq);
   224		device_addr = virtqueue_get_used_addr(vq);
   225	
   226		if (ops->set_vq_address(vdpa, index,
   227					desc_addr, driver_addr,
   228					device_addr)) {
   229			err = -EINVAL;
   230			goto err_vq;
   231		}
   232	
   233		/* reset virtqueue state index */
   234		if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
   235			struct vdpa_vq_state_packed *s = &state.packed;
   236	
   237			s->last_avail_counter = 1;
   238			s->last_avail_idx = 0;
   239			s->last_used_counter = 1;
   240			s->last_used_idx = 0;
   241		}
   242		err = ops->set_vq_state(vdpa, index, &state);
   243		if (err)
   244			goto err_vq;
   245	
   246		ops->set_vq_ready(vdpa, index, 1);
   247	
   248		vq->priv = info;
   249		info->vq = vq;
   250	
   251		spin_lock_irqsave(&vd_dev->lock, flags);
   252		list_add(&info->node, &vd_dev->virtqueues);
   253		spin_unlock_irqrestore(&vd_dev->lock, flags);
   254	
   255		return vq;
   256	
   257	err_vq:
   258		vring_del_virtqueue(vq);
   259	error_new_virtqueue:
   260		ops->set_vq_ready(vdpa, index, 0);
   261		/* VDPA driver should make sure vq is stopeed here */
   262		WARN_ON(ops->get_vq_ready(vdpa, index));
   263		kfree(info);
   264		return ERR_PTR(err);
   265	}
   266	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-21 10:15 ` [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null Xuan Zhuo
  2024-03-22 11:56   ` David Hildenbrand
@ 2024-03-22 19:16   ` Daniel Verkamp
  2024-03-22 21:02     ` David Hildenbrand
  1 sibling, 1 reply; 19+ messages in thread
From: Daniel Verkamp @ 2024-03-22 19:16 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: virtualization, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Hans de Goede, Ilpo Järvinen, Vadim Pasternak,
	Bjorn Andersson, Mathieu Poirier, Cornelia Huck, Halil Pasic,
	Eric Farman, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	David Hildenbrand, Jason Wang, linux-um, platform-driver-x86,
	linux-remoteproc, linux-s390, kvm

On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> Currently, the init_vqs function within the virtio_balloon driver relies
> on the condition that certain names array entries are null in order to
> skip the initialization of some virtual queues (vqs). This behavior is
> unique to this part of the codebase. In an upcoming commit, we plan to
> eliminate this dependency by removing the function entirely. Therefore,
> with this change, we are ensuring that the virtio_balloon no longer
> depends on the aforementioned function.

This is a behavior change, and I believe means that the driver no
longer follows the spec [1].

For example, the spec says that virtqueue 4 is reporting_vq, and
reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
but there is no mention of its virtqueue number changing if other
features are not set. If a device/driver combination negotiates
VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
that reporting_vq should still be vq number 4, and vq 2 and 3 should
be unused. This patch would make the reporting_vq use vq 2 instead in
this case.

If the new behavior is truly intended, then the spec does not match
reality, and it would need to be changed first (IMO); however,
changing the spec would mean that any devices implemented correctly
per the previous spec would now be wrong, so some kind of mechanism
for detecting the new behavior would be warranted, e.g. a new
non-device-specific virtio feature flag.

I have brought this up previously on the virtio-comment list [2], but
it did not receive any satisfying answers at that time.

Thanks,
-- Daniel

[1]: https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-3140005
[2]: https://lists.oasis-open.org/archives/virtio-comment/202308/msg00280.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-22 19:16   ` Daniel Verkamp
@ 2024-03-22 21:02     ` David Hildenbrand
  2024-03-25  6:08       ` Xuan Zhuo
  0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand @ 2024-03-22 21:02 UTC (permalink / raw)
  To: Daniel Verkamp, Xuan Zhuo
  Cc: virtualization, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Hans de Goede, Ilpo Järvinen, Vadim Pasternak,
	Bjorn Andersson, Mathieu Poirier, Cornelia Huck, Halil Pasic,
	Eric Farman, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	Jason Wang, linux-um, platform-driver-x86, linux-remoteproc,
	linux-s390, kvm

On 22.03.24 20:16, Daniel Verkamp wrote:
> On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>>
>> Currently, the init_vqs function within the virtio_balloon driver relies
>> on the condition that certain names array entries are null in order to
>> skip the initialization of some virtual queues (vqs). This behavior is
>> unique to this part of the codebase. In an upcoming commit, we plan to
>> eliminate this dependency by removing the function entirely. Therefore,
>> with this change, we are ensuring that the virtio_balloon no longer
>> depends on the aforementioned function.
> 
> This is a behavior change, and I believe means that the driver no
> longer follows the spec [1].
> 
> For example, the spec says that virtqueue 4 is reporting_vq, and
> reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
> but there is no mention of its virtqueue number changing if other
> features are not set. If a device/driver combination negotiates
> VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
> VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
> that reporting_vq should still be vq number 4, and vq 2 and 3 should
> be unused. This patch would make the reporting_vq use vq 2 instead in
> this case.
> 
> If the new behavior is truly intended, then the spec does not match
> reality, and it would need to be changed first (IMO); however,
> changing the spec would mean that any devices implemented correctly
> per the previous spec would now be wrong, so some kind of mechanism
> for detecting the new behavior would be warranted, e.g. a new
> non-device-specific virtio feature flag.
> 
> I have brought this up previously on the virtio-comment list [2], but
> it did not receive any satisfying answers at that time.

Rings a bell, but staring at this patch, I thought that there would be
no behavioral change. Maybe I missed it :/

I stared at virtio_ccw_find_vqs(), and it contains:

	for (i = 0; i < nvqs; ++i) {
		if (!names[i]) {
			vqs[i] = NULL;
			continue;
		}

		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
					     names[i], ctx ? ctx[i] : false,
					     ccw);
		if (IS_ERR(vqs[i])) {
			ret = PTR_ERR(vqs[i]);
			vqs[i] = NULL;
			goto out;
		}
	}

We increment queue_idx only if an entry was not NULL. SO I thought no
behavioral change? (at least on s390x :) )

It's late here in Germany, so maybe I'm missing something.

-- 
Cheers,

David / dhildenb


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters
  2024-03-21 10:15 ` [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters Xuan Zhuo
  2024-03-22 14:10   ` kernel test robot
@ 2024-03-23  0:29   ` kernel test robot
  1 sibling, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-03-23  0:29 UTC (permalink / raw)
  To: Xuan Zhuo; +Cc: llvm, oe-kbuild-all

Hi Xuan,

kernel test robot noticed the following build errors:

[auto build test ERROR on remoteproc/rproc-next]
[also build test ERROR on v6.8]
[cannot apply to s390/features linus/master uml/next uml/fixes next-20240322]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Xuan-Zhuo/virtio_balloon-remove-the-dependence-where-names-is-null/20240321-182217
base:   git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rproc-next
patch link:    https://lore.kernel.org/r/20240321101532.59272-4-xuanzhuo%40linux.alibaba.com
patch subject: [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters
config: arm-randconfig-002-20240322 (https://download.01.org/0day-ci/archive/20240323/202403230820.okiEkuGQ-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 23de3862dce582ce91c1aa914467d982cb1a73b4)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240323/202403230820.okiEkuGQ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403230820.okiEkuGQ-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/virtio/virtio_vdpa.c:17:
   In file included from include/linux/virtio.h:7:
   In file included from include/linux/scatterlist.h:8:
   In file included from include/linux/mm.h:2188:
   include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     522 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/virtio/virtio_vdpa.c:216:36: error: no member named 'cfg_idx' in 'struct virtio_vq_config'
     216 |         cb.callback = cfg->callbacks[cfg->cfg_idx] ? virtio_vdpa_virtqueue_cb : NULL;
         |                                      ~~~  ^
   1 warning and 1 error generated.


vim +216 drivers/virtio/virtio_vdpa.c

  > 17	#include <linux/virtio.h>
    18	#include <linux/vdpa.h>
    19	#include <linux/virtio_config.h>
    20	#include <linux/virtio_ring.h>
    21	
    22	#define MOD_VERSION  "0.1"
    23	#define MOD_AUTHOR   "Jason Wang <jasowang@redhat.com>"
    24	#define MOD_DESC     "vDPA bus driver for virtio devices"
    25	#define MOD_LICENSE  "GPL v2"
    26	
    27	struct virtio_vdpa_device {
    28		struct virtio_device vdev;
    29		struct vdpa_device *vdpa;
    30		u64 features;
    31	
    32		/* The lock to protect virtqueue list */
    33		spinlock_t lock;
    34		/* List of virtio_vdpa_vq_info */
    35		struct list_head virtqueues;
    36	};
    37	
    38	struct virtio_vdpa_vq_info {
    39		/* the actual virtqueue */
    40		struct virtqueue *vq;
    41	
    42		/* the list node for the virtqueues list */
    43		struct list_head node;
    44	};
    45	
    46	static inline struct virtio_vdpa_device *
    47	to_virtio_vdpa_device(struct virtio_device *dev)
    48	{
    49		return container_of(dev, struct virtio_vdpa_device, vdev);
    50	}
    51	
    52	static struct vdpa_device *vd_get_vdpa(struct virtio_device *vdev)
    53	{
    54		return to_virtio_vdpa_device(vdev)->vdpa;
    55	}
    56	
    57	static void virtio_vdpa_get(struct virtio_device *vdev, unsigned int offset,
    58				    void *buf, unsigned int len)
    59	{
    60		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
    61	
    62		vdpa_get_config(vdpa, offset, buf, len);
    63	}
    64	
    65	static void virtio_vdpa_set(struct virtio_device *vdev, unsigned int offset,
    66				    const void *buf, unsigned int len)
    67	{
    68		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
    69	
    70		vdpa_set_config(vdpa, offset, buf, len);
    71	}
    72	
    73	static u32 virtio_vdpa_generation(struct virtio_device *vdev)
    74	{
    75		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
    76		const struct vdpa_config_ops *ops = vdpa->config;
    77	
    78		if (ops->get_generation)
    79			return ops->get_generation(vdpa);
    80	
    81		return 0;
    82	}
    83	
    84	static u8 virtio_vdpa_get_status(struct virtio_device *vdev)
    85	{
    86		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
    87		const struct vdpa_config_ops *ops = vdpa->config;
    88	
    89		return ops->get_status(vdpa);
    90	}
    91	
    92	static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status)
    93	{
    94		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
    95	
    96		return vdpa_set_status(vdpa, status);
    97	}
    98	
    99	static void virtio_vdpa_reset(struct virtio_device *vdev)
   100	{
   101		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
   102	
   103		vdpa_reset(vdpa, 0);
   104	}
   105	
   106	static bool virtio_vdpa_notify(struct virtqueue *vq)
   107	{
   108		struct vdpa_device *vdpa = vd_get_vdpa(vq->vdev);
   109		const struct vdpa_config_ops *ops = vdpa->config;
   110	
   111		ops->kick_vq(vdpa, vq->index);
   112	
   113		return true;
   114	}
   115	
   116	static bool virtio_vdpa_notify_with_data(struct virtqueue *vq)
   117	{
   118		struct vdpa_device *vdpa = vd_get_vdpa(vq->vdev);
   119		const struct vdpa_config_ops *ops = vdpa->config;
   120		u32 data = vring_notification_data(vq);
   121	
   122		ops->kick_vq_with_data(vdpa, data);
   123	
   124		return true;
   125	}
   126	
   127	static irqreturn_t virtio_vdpa_config_cb(void *private)
   128	{
   129		struct virtio_vdpa_device *vd_dev = private;
   130	
   131		virtio_config_changed(&vd_dev->vdev);
   132	
   133		return IRQ_HANDLED;
   134	}
   135	
   136	static irqreturn_t virtio_vdpa_virtqueue_cb(void *private)
   137	{
   138		struct virtio_vdpa_vq_info *info = private;
   139	
   140		return vring_interrupt(0, info->vq);
   141	}
   142	
   143	static struct virtqueue *
   144	virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
   145			     struct virtio_vq_config *cfg)
   146	{
   147		struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
   148		struct vdpa_device *vdpa = vd_get_vdpa(vdev);
   149		struct device *dma_dev;
   150		const struct vdpa_config_ops *ops = vdpa->config;
   151		struct virtio_vdpa_vq_info *info;
   152		bool (*notify)(struct virtqueue *vq) = virtio_vdpa_notify;
   153		struct vdpa_callback cb;
   154		struct virtqueue *vq;
   155		u64 desc_addr, driver_addr, device_addr;
   156		/* Assume split virtqueue, switch to packed if necessary */
   157		struct vdpa_vq_state state = {0};
   158		unsigned long flags;
   159		u32 align, max_num, min_num = 1;
   160		bool may_reduce_num = true;
   161		int err;
   162	
   163		if (index >= vdpa->nvqs)
   164			return ERR_PTR(-ENOENT);
   165	
   166		/* We cannot accept VIRTIO_F_NOTIFICATION_DATA without kick_vq_with_data */
   167		if (__virtio_test_bit(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
   168			if (ops->kick_vq_with_data)
   169				notify = virtio_vdpa_notify_with_data;
   170			else
   171				__virtio_clear_bit(vdev, VIRTIO_F_NOTIFICATION_DATA);
   172		}
   173	
   174		/* Queue shouldn't already be set up. */
   175		if (ops->get_vq_ready(vdpa, index))
   176			return ERR_PTR(-ENOENT);
   177	
   178		/* Allocate and fill out our active queue description */
   179		info = kmalloc(sizeof(*info), GFP_KERNEL);
   180		if (!info)
   181			return ERR_PTR(-ENOMEM);
   182	
   183		max_num = ops->get_vq_num_max(vdpa);
   184		if (max_num == 0) {
   185			err = -ENOENT;
   186			goto error_new_virtqueue;
   187		}
   188	
   189		if (ops->get_vq_num_min)
   190			min_num = ops->get_vq_num_min(vdpa);
   191	
   192		may_reduce_num = (max_num == min_num) ? false : true;
   193	
   194		/* Create the vring */
   195		align = ops->get_vq_align(vdpa);
   196	
   197		if (ops->get_vq_dma_dev)
   198			dma_dev = ops->get_vq_dma_dev(vdpa, index);
   199		else
   200			dma_dev = vdpa_get_dma_dev(vdpa);
   201		vq = vring_create_virtqueue_dma(index, max_num, align, vdev,
   202						true, may_reduce_num,
   203						cfg->ctx ? cfg->ctx[index] : false,
   204						notify,
   205						cfg->callbacks[index],
   206						cfg->names[index],
   207						dma_dev);
   208		if (!vq) {
   209			err = -ENOMEM;
   210			goto error_new_virtqueue;
   211		}
   212	
   213		vq->num_max = max_num;
   214	
   215		/* Setup virtqueue callback */
 > 216		cb.callback = cfg->callbacks[cfg->cfg_idx] ? virtio_vdpa_virtqueue_cb : NULL;
   217		cb.private = info;
   218		cb.trigger = NULL;
   219		ops->set_vq_cb(vdpa, index, &cb);
   220		ops->set_vq_num(vdpa, index, virtqueue_get_vring_size(vq));
   221	
   222		desc_addr = virtqueue_get_desc_addr(vq);
   223		driver_addr = virtqueue_get_avail_addr(vq);
   224		device_addr = virtqueue_get_used_addr(vq);
   225	
   226		if (ops->set_vq_address(vdpa, index,
   227					desc_addr, driver_addr,
   228					device_addr)) {
   229			err = -EINVAL;
   230			goto err_vq;
   231		}
   232	
   233		/* reset virtqueue state index */
   234		if (virtio_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
   235			struct vdpa_vq_state_packed *s = &state.packed;
   236	
   237			s->last_avail_counter = 1;
   238			s->last_avail_idx = 0;
   239			s->last_used_counter = 1;
   240			s->last_used_idx = 0;
   241		}
   242		err = ops->set_vq_state(vdpa, index, &state);
   243		if (err)
   244			goto err_vq;
   245	
   246		ops->set_vq_ready(vdpa, index, 1);
   247	
   248		vq->priv = info;
   249		info->vq = vq;
   250	
   251		spin_lock_irqsave(&vd_dev->lock, flags);
   252		list_add(&info->node, &vd_dev->virtqueues);
   253		spin_unlock_irqrestore(&vd_dev->lock, flags);
   254	
   255		return vq;
   256	
   257	err_vq:
   258		vring_del_virtqueue(vq);
   259	error_new_virtqueue:
   260		ops->set_vq_ready(vdpa, index, 0);
   261		/* VDPA driver should make sure vq is stopeed here */
   262		WARN_ON(ops->get_vq_ready(vdpa, index));
   263		kfree(info);
   264		return ERR_PTR(err);
   265	}
   266	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-22 11:56   ` David Hildenbrand
@ 2024-03-25  6:03     ` Xuan Zhuo
  0 siblings, 0 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-25  6:03 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Richard Weinberger, Anton Ivanov, Johannes Berg, Hans de Goede,
	Ilpo Järvinen, Vadim Pasternak, Bjorn Andersson,
	Mathieu Poirier, Cornelia Huck, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	Jason Wang, linux-um, platform-driver-x86, linux-remoteproc,
	linux-s390, kvm, virtualization

On Fri, 22 Mar 2024 12:56:46 +0100, David Hildenbrand <david@redhat.com> wrote:
> On 21.03.24 11:15, Xuan Zhuo wrote:
> > Currently, the init_vqs function within the virtio_balloon driver relies
> > on the condition that certain names array entries are null in order to
> > skip the initialization of some virtual queues (vqs). This behavior is
> > unique to this part of the codebase. In an upcoming commit, we plan to
> > eliminate this dependency by removing the function entirely. Therefore,
> > with this change, we are ensuring that the virtio_balloon no longer
> > depends on the aforementioned function.
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >   drivers/virtio/virtio_balloon.c | 41 +++++++++++++++------------------
> >   1 file changed, 19 insertions(+), 22 deletions(-)
> >
> > diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
> > index 1f5b3dd31fcf..becc12a05407 100644
> > --- a/drivers/virtio/virtio_balloon.c
> > +++ b/drivers/virtio/virtio_balloon.c
> > @@ -531,49 +531,46 @@ static int init_vqs(struct virtio_balloon *vb)
> >   	struct virtqueue *vqs[VIRTIO_BALLOON_VQ_MAX];
> >   	vq_callback_t *callbacks[VIRTIO_BALLOON_VQ_MAX];
> >   	const char *names[VIRTIO_BALLOON_VQ_MAX];
> > -	int err;
> > +	int err, nvqs, idx;
> >
> > -	/*
> > -	 * Inflateq and deflateq are used unconditionally. The names[]
> > -	 * will be NULL if the related feature is not enabled, which will
> > -	 * cause no allocation for the corresponding virtqueue in find_vqs.
> > -	 */
> >   	callbacks[VIRTIO_BALLOON_VQ_INFLATE] = balloon_ack;
> >   	names[VIRTIO_BALLOON_VQ_INFLATE] = "inflate";
> >   	callbacks[VIRTIO_BALLOON_VQ_DEFLATE] = balloon_ack;
> >   	names[VIRTIO_BALLOON_VQ_DEFLATE] = "deflate";
>
> I'd remove the static dependencies here completely and do it
> consistently:
>
> nvqs = 0;
>
> callbacks[nvqs] = balloon_ack;
> names[nvqs++] = "inflate";
> callbacks[nvqs] = balloon_ack;
> names[nvqs++] = "deflate";
>
>
> > -	callbacks[VIRTIO_BALLOON_VQ_STATS] = NULL;
> > -	names[VIRTIO_BALLOON_VQ_STATS] = NULL;
> > -	callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
> > -	names[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
> > -	names[VIRTIO_BALLOON_VQ_REPORTING] = NULL;
> > +
> > +	nvqs = VIRTIO_BALLOON_VQ_DEFLATE + 1;
> >
> >   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
> > -		names[VIRTIO_BALLOON_VQ_STATS] = "stats";
> > -		callbacks[VIRTIO_BALLOON_VQ_STATS] = stats_request;
> > +		names[nvqs] = "stats";
> > +		callbacks[nvqs] = stats_request;
> > +		++nvqs;
>
> callbacks[nvqs++] = stats_request;
>
> If you prefer to keep it separate, "nvqs++" please.
>
> ... same here:
>
> idx = 0;
> vb->inflate_vq = vqs[idx++];
> vb->deflate_vq = vqs[idx++];
>
> ...
>
> >
> >   	vb->inflate_vq = vqs[VIRTIO_BALLOON_VQ_INFLATE];
> >   	vb->deflate_vq = vqs[VIRTIO_BALLOON_VQ_DEFLATE];
> > +
> > +	idx = VIRTIO_BALLOON_VQ_DEFLATE + 1;
> > +
> >   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
> >   		struct scatterlist sg;
> >   		unsigned int num_stats;
> > -		vb->stats_vq = vqs[VIRTIO_BALLOON_VQ_STATS];
> > +		vb->stats_vq = vqs[idx++];
> >
> >   		/*
> >   		 * Prime this virtqueue with one buffer so the hypervisor can
> > @@ -593,10 +590,10 @@ static int init_vqs(struct virtio_balloon *vb)
> >   	}
> >
> >   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
> > -		vb->free_page_vq = vqs[VIRTIO_BALLOON_VQ_FREE_PAGE];
> > +		vb->free_page_vq = vqs[idx++];
> >
> >   	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING))
> > -		vb->reporting_vq = vqs[VIRTIO_BALLOON_VQ_REPORTING];
> > +		vb->reporting_vq = vqs[idx++];
> >
>
> Apart from that LGTM

Will fix in next version.

Thanks.


>
> --
> Cheers,
>
> David / dhildenb
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-22 21:02     ` David Hildenbrand
@ 2024-03-25  6:08       ` Xuan Zhuo
  2024-03-25  9:11         ` David Hildenbrand
  2024-03-25  9:44         ` Cornelia Huck
  0 siblings, 2 replies; 19+ messages in thread
From: Xuan Zhuo @ 2024-03-25  6:08 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: virtualization, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Hans de Goede, Ilpo Järvinen, Vadim Pasternak,
	Bjorn Andersson, Mathieu Poirier, Cornelia Huck, Halil Pasic,
	Eric Farman, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	Jason Wang, linux-um, platform-driver-x86, linux-remoteproc,
	linux-s390, kvm, Daniel Verkamp

On Fri, 22 Mar 2024 22:02:27 +0100, David Hildenbrand <david@redhat.com> wrote:
> On 22.03.24 20:16, Daniel Verkamp wrote:
> > On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >>
> >> Currently, the init_vqs function within the virtio_balloon driver relies
> >> on the condition that certain names array entries are null in order to
> >> skip the initialization of some virtual queues (vqs). This behavior is
> >> unique to this part of the codebase. In an upcoming commit, we plan to
> >> eliminate this dependency by removing the function entirely. Therefore,
> >> with this change, we are ensuring that the virtio_balloon no longer
> >> depends on the aforementioned function.
> >
> > This is a behavior change, and I believe means that the driver no
> > longer follows the spec [1].
> >
> > For example, the spec says that virtqueue 4 is reporting_vq, and
> > reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
> > but there is no mention of its virtqueue number changing if other
> > features are not set. If a device/driver combination negotiates
> > VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
> > VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
> > that reporting_vq should still be vq number 4, and vq 2 and 3 should
> > be unused. This patch would make the reporting_vq use vq 2 instead in
> > this case.
> >
> > If the new behavior is truly intended, then the spec does not match
> > reality, and it would need to be changed first (IMO); however,
> > changing the spec would mean that any devices implemented correctly
> > per the previous spec would now be wrong, so some kind of mechanism
> > for detecting the new behavior would be warranted, e.g. a new
> > non-device-specific virtio feature flag.
> >
> > I have brought this up previously on the virtio-comment list [2], but
> > it did not receive any satisfying answers at that time.
>
> Rings a bell, but staring at this patch, I thought that there would be
> no behavioral change. Maybe I missed it :/
>
> I stared at virtio_ccw_find_vqs(), and it contains:
>
> 	for (i = 0; i < nvqs; ++i) {
> 		if (!names[i]) {
> 			vqs[i] = NULL;
> 			continue;
> 		}
>
> 		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
> 					     names[i], ctx ? ctx[i] : false,
> 					     ccw);
> 		if (IS_ERR(vqs[i])) {
> 			ret = PTR_ERR(vqs[i]);
> 			vqs[i] = NULL;
> 			goto out;
> 		}
> 	}
>
> We increment queue_idx only if an entry was not NULL. SO I thought no
> behavioral change? (at least on s390x :) )
>
> It's late here in Germany, so maybe I'm missing something.

I think we've encountered a tricky issue. Currently, all transports handle queue
id by incrementing them in order, without skipping any queue id. So, I'm quite
surprised that my changes would affect the spec. The fact that the
'names' value is null is just a small trick in the Linux kernel implementation
and should not have an impact on the queue id.

I believe that my recent modification will not affect the spec. So, let's
consider the issues with this patch set separately for now. Regarding the Memory
Balloon Device, it has been operational for many years, and perhaps we should
add to the spec that if a certain vq does not exist, then subsequent vqs will
take over its id.

Thanks.



>
> --
> Cheers,
>
> David / dhildenb
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-25  6:08       ` Xuan Zhuo
@ 2024-03-25  9:11         ` David Hildenbrand
  2024-03-26 20:23           ` Daniel Verkamp
  2024-03-25  9:44         ` Cornelia Huck
  1 sibling, 1 reply; 19+ messages in thread
From: David Hildenbrand @ 2024-03-25  9:11 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: virtualization, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Hans de Goede, Ilpo Järvinen, Vadim Pasternak,
	Bjorn Andersson, Mathieu Poirier, Cornelia Huck, Halil Pasic,
	Eric Farman, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	Jason Wang, linux-um, platform-driver-x86, linux-remoteproc,
	linux-s390, kvm, Daniel Verkamp

On 25.03.24 07:08, Xuan Zhuo wrote:
> On Fri, 22 Mar 2024 22:02:27 +0100, David Hildenbrand <david@redhat.com> wrote:
>> On 22.03.24 20:16, Daniel Verkamp wrote:
>>> On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>>>>
>>>> Currently, the init_vqs function within the virtio_balloon driver relies
>>>> on the condition that certain names array entries are null in order to
>>>> skip the initialization of some virtual queues (vqs). This behavior is
>>>> unique to this part of the codebase. In an upcoming commit, we plan to
>>>> eliminate this dependency by removing the function entirely. Therefore,
>>>> with this change, we are ensuring that the virtio_balloon no longer
>>>> depends on the aforementioned function.
>>>
>>> This is a behavior change, and I believe means that the driver no
>>> longer follows the spec [1].
>>>
>>> For example, the spec says that virtqueue 4 is reporting_vq, and
>>> reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
>>> but there is no mention of its virtqueue number changing if other
>>> features are not set. If a device/driver combination negotiates
>>> VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
>>> VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
>>> that reporting_vq should still be vq number 4, and vq 2 and 3 should
>>> be unused. This patch would make the reporting_vq use vq 2 instead in
>>> this case.
>>>
>>> If the new behavior is truly intended, then the spec does not match
>>> reality, and it would need to be changed first (IMO); however,
>>> changing the spec would mean that any devices implemented correctly
>>> per the previous spec would now be wrong, so some kind of mechanism
>>> for detecting the new behavior would be warranted, e.g. a new
>>> non-device-specific virtio feature flag.
>>>
>>> I have brought this up previously on the virtio-comment list [2], but
>>> it did not receive any satisfying answers at that time.
>>
>> Rings a bell, but staring at this patch, I thought that there would be
>> no behavioral change. Maybe I missed it :/
>>
>> I stared at virtio_ccw_find_vqs(), and it contains:
>>
>> 	for (i = 0; i < nvqs; ++i) {
>> 		if (!names[i]) {
>> 			vqs[i] = NULL;
>> 			continue;
>> 		}
>>
>> 		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
>> 					     names[i], ctx ? ctx[i] : false,
>> 					     ccw);
>> 		if (IS_ERR(vqs[i])) {
>> 			ret = PTR_ERR(vqs[i]);
>> 			vqs[i] = NULL;
>> 			goto out;
>> 		}
>> 	}
>>
>> We increment queue_idx only if an entry was not NULL. SO I thought no
>> behavioral change? (at least on s390x :) )
>>
>> It's late here in Germany, so maybe I'm missing something.
> 
> I think we've encountered a tricky issue. Currently, all transports handle queue
> id by incrementing them in order, without skipping any queue id. So, I'm quite
> surprised that my changes would affect the spec. The fact that the
> 'names' value is null is just a small trick in the Linux kernel implementation
> and should not have an impact on the queue id.
> 
> I believe that my recent modification will not affect the spec. So, let's
> consider the issues with this patch set separately for now. Regarding the Memory
> Balloon Device, it has been operational for many years, and perhaps we should
> add to the spec that if a certain vq does not exist, then subsequent vqs will
> take over its id.

Right, if I am not missing something your patch should have no 
functional change in that regard (that the current 
behavior/implementation might not match the spec is a different discussion).

@Daniel, if I'm missing something, please shout.

-- 
Cheers,

David / dhildenb


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-25  6:08       ` Xuan Zhuo
  2024-03-25  9:11         ` David Hildenbrand
@ 2024-03-25  9:44         ` Cornelia Huck
  2024-03-26  4:11           ` Jason Wang
  1 sibling, 1 reply; 19+ messages in thread
From: Cornelia Huck @ 2024-03-25  9:44 UTC (permalink / raw)
  To: Xuan Zhuo, David Hildenbrand
  Cc: virtualization, Richard Weinberger, Anton Ivanov, Johannes Berg,
	Hans de Goede, Ilpo Järvinen, Vadim Pasternak,
	Bjorn Andersson, Mathieu Poirier, Halil Pasic, Eric Farman,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	Jason Wang, linux-um, platform-driver-x86, linux-remoteproc,
	linux-s390, kvm, Daniel Verkamp

On Mon, Mar 25 2024, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:

> On Fri, 22 Mar 2024 22:02:27 +0100, David Hildenbrand <david@redhat.com> wrote:
>> On 22.03.24 20:16, Daniel Verkamp wrote:
>> > On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>> >>
>> >> Currently, the init_vqs function within the virtio_balloon driver relies
>> >> on the condition that certain names array entries are null in order to
>> >> skip the initialization of some virtual queues (vqs). This behavior is
>> >> unique to this part of the codebase. In an upcoming commit, we plan to
>> >> eliminate this dependency by removing the function entirely. Therefore,
>> >> with this change, we are ensuring that the virtio_balloon no longer
>> >> depends on the aforementioned function.
>> >
>> > This is a behavior change, and I believe means that the driver no
>> > longer follows the spec [1].
>> >
>> > For example, the spec says that virtqueue 4 is reporting_vq, and
>> > reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
>> > but there is no mention of its virtqueue number changing if other
>> > features are not set. If a device/driver combination negotiates
>> > VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
>> > VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
>> > that reporting_vq should still be vq number 4, and vq 2 and 3 should
>> > be unused. This patch would make the reporting_vq use vq 2 instead in
>> > this case.
>> >
>> > If the new behavior is truly intended, then the spec does not match
>> > reality, and it would need to be changed first (IMO); however,
>> > changing the spec would mean that any devices implemented correctly
>> > per the previous spec would now be wrong, so some kind of mechanism
>> > for detecting the new behavior would be warranted, e.g. a new
>> > non-device-specific virtio feature flag.
>> >
>> > I have brought this up previously on the virtio-comment list [2], but
>> > it did not receive any satisfying answers at that time.

I had missed it back then, but now that I read it, I realize that we
really have a bit of a mess here :/

>>
>> Rings a bell, but staring at this patch, I thought that there would be
>> no behavioral change. Maybe I missed it :/
>>
>> I stared at virtio_ccw_find_vqs(), and it contains:
>>
>> 	for (i = 0; i < nvqs; ++i) {
>> 		if (!names[i]) {
>> 			vqs[i] = NULL;
>> 			continue;
>> 		}
>>
>> 		vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
>> 					     names[i], ctx ? ctx[i] : false,
>> 					     ccw);
>> 		if (IS_ERR(vqs[i])) {
>> 			ret = PTR_ERR(vqs[i]);
>> 			vqs[i] = NULL;
>> 			goto out;
>> 		}
>> 	}
>>
>> We increment queue_idx only if an entry was not NULL. SO I thought no
>> behavioral change? (at least on s390x :) )

The code for pci behaves in the same way.

>>
>> It's late here in Germany, so maybe I'm missing something.
>
> I think we've encountered a tricky issue. Currently, all transports handle queue
> id by incrementing them in order, without skipping any queue id. So, I'm quite
> surprised that my changes would affect the spec. The fact that the
> 'names' value is null is just a small trick in the Linux kernel implementation
> and should not have an impact on the queue id.
>
> I believe that my recent modification will not affect the spec. So, let's
> consider the issues with this patch set separately for now. Regarding the Memory
> Balloon Device, it has been operational for many years, and perhaps we should
> add to the spec that if a certain vq does not exist, then subsequent vqs will
> take over its id.

The changes here do not really seem to affect the spec issue that Daniel
had noted, unless I'm reading the code wrong.

However, we should try to address the spec mess, where we have at least
some of the most popular/important implementations behaving differently
than the spec describes... I would suggest to discuss that on the virtio
lists -- but they are still dead, and at this point I'm just hoping
they'll come back eventually :/


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-25  9:44         ` Cornelia Huck
@ 2024-03-26  4:11           ` Jason Wang
  2024-03-26  4:25             ` Jason Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Jason Wang @ 2024-03-26  4:11 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Xuan Zhuo, David Hildenbrand, virtualization, Richard Weinberger,
	Anton Ivanov, Johannes Berg, Hans de Goede, Ilpo Järvinen,
	Vadim Pasternak, Bjorn Andersson, Mathieu Poirier, Halil Pasic,
	Eric Farman, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	linux-um, platform-driver-x86, linux-remoteproc, linux-s390, kvm,
	Daniel Verkamp

On Mon, Mar 25, 2024 at 5:44 PM Cornelia Huck <cohuck@redhat.com> wrote:
>
> On Mon, Mar 25 2024, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> > On Fri, 22 Mar 2024 22:02:27 +0100, David Hildenbrand <david@redhat.com> wrote:
> >> On 22.03.24 20:16, Daniel Verkamp wrote:
> >> > On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >> >>
> >> >> Currently, the init_vqs function within the virtio_balloon driver relies
> >> >> on the condition that certain names array entries are null in order to
> >> >> skip the initialization of some virtual queues (vqs). This behavior is
> >> >> unique to this part of the codebase. In an upcoming commit, we plan to
> >> >> eliminate this dependency by removing the function entirely. Therefore,
> >> >> with this change, we are ensuring that the virtio_balloon no longer
> >> >> depends on the aforementioned function.
> >> >
> >> > This is a behavior change, and I believe means that the driver no
> >> > longer follows the spec [1].
> >> >
> >> > For example, the spec says that virtqueue 4 is reporting_vq, and
> >> > reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
> >> > but there is no mention of its virtqueue number changing if other
> >> > features are not set. If a device/driver combination negotiates
> >> > VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
> >> > VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
> >> > that reporting_vq should still be vq number 4, and vq 2 and 3 should
> >> > be unused. This patch would make the reporting_vq use vq 2 instead in
> >> > this case.
> >> >
> >> > If the new behavior is truly intended, then the spec does not match
> >> > reality, and it would need to be changed first (IMO); however,
> >> > changing the spec would mean that any devices implemented correctly
> >> > per the previous spec would now be wrong, so some kind of mechanism
> >> > for detecting the new behavior would be warranted, e.g. a new
> >> > non-device-specific virtio feature flag.
> >> >
> >> > I have brought this up previously on the virtio-comment list [2], but
> >> > it did not receive any satisfying answers at that time.
>
> I had missed it back then, but now that I read it, I realize that we
> really have a bit of a mess here :/
>
> >>
> >> Rings a bell, but staring at this patch, I thought that there would be
> >> no behavioral change. Maybe I missed it :/
> >>
> >> I stared at virtio_ccw_find_vqs(), and it contains:
> >>
> >>      for (i = 0; i < nvqs; ++i) {
> >>              if (!names[i]) {
> >>                      vqs[i] = NULL;
> >>                      continue;
> >>              }
> >>
> >>              vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
> >>                                           names[i], ctx ? ctx[i] : false,
> >>                                           ccw);
> >>              if (IS_ERR(vqs[i])) {
> >>                      ret = PTR_ERR(vqs[i]);
> >>                      vqs[i] = NULL;
> >>                      goto out;
> >>              }
> >>      }
> >>
> >> We increment queue_idx only if an entry was not NULL. SO I thought no
> >> behavioral change? (at least on s390x :) )
>
> The code for pci behaves in the same way.
>
> >>
> >> It's late here in Germany, so maybe I'm missing something.
> >
> > I think we've encountered a tricky issue. Currently, all transports handle queue
> > id by incrementing them in order, without skipping any queue id. So, I'm quite
> > surprised that my changes would affect the spec. The fact that the
> > 'names' value is null is just a small trick in the Linux kernel implementation
> > and should not have an impact on the queue id.
> >
> > I believe that my recent modification will not affect the spec. So, let's
> > consider the issues with this patch set separately for now. Regarding the Memory
> > Balloon Device, it has been operational for many years, and perhaps we should
> > add to the spec that if a certain vq does not exist, then subsequent vqs will
> > take over its id.
>
> The changes here do not really seem to affect the spec issue that Daniel
> had noted, unless I'm reading the code wrong.

Spec seems to be wrong here:

5.5.2 Virtqueues

0 inflateq 1 deflateq 2 statsq 3 free_page_vq4 r eporting_vq

And this is the Qemu implementation:

5.5.2 Virtqueues

    s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
    s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
    s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);

    if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
        s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE,
                                           virtio_balloon_handle_free_page_vq);
        precopy_add_notifier(&s->free_page_hint_notify);

        object_ref(OBJECT(s->iothread));
        s->free_page_bh =
aio_bh_new_guarded(iothread_get_aio_context(s->iothread),

virtio_ballloon_get_free_page_hints, s,
                                             &dev->mem_reentrancy_guard);
    }

    if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) {
        s->reporting_vq = virtio_add_queue(vdev, 32,
                                           virtio_balloon_handle_report);
    }

We need to fix it.

>
> However, we should try to address the spec mess, where we have at least
> some of the most popular/important implementations behaving differently
> than the spec describes... I would suggest to discuss that on the virtio
> lists -- but they are still dead, and at this point I'm just hoping
> they'll come back eventually :/
>

Thanks


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-26  4:11           ` Jason Wang
@ 2024-03-26  4:25             ` Jason Wang
  0 siblings, 0 replies; 19+ messages in thread
From: Jason Wang @ 2024-03-26  4:25 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Xuan Zhuo, David Hildenbrand, virtualization, Richard Weinberger,
	Anton Ivanov, Johannes Berg, Hans de Goede, Ilpo Järvinen,
	Vadim Pasternak, Bjorn Andersson, Mathieu Poirier, Halil Pasic,
	Eric Farman, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Michael S. Tsirkin,
	linux-um, platform-driver-x86, linux-remoteproc, linux-s390, kvm,
	Daniel Verkamp

On Tue, Mar 26, 2024 at 12:11 PM Jason Wang <jasowang@redhat.com> wrote:
>
> On Mon, Mar 25, 2024 at 5:44 PM Cornelia Huck <cohuck@redhat.com> wrote:
> >
> > On Mon, Mar 25 2024, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > > On Fri, 22 Mar 2024 22:02:27 +0100, David Hildenbrand <david@redhat.com> wrote:
> > >> On 22.03.24 20:16, Daniel Verkamp wrote:
> > >> > On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > >> >>
> > >> >> Currently, the init_vqs function within the virtio_balloon driver relies
> > >> >> on the condition that certain names array entries are null in order to
> > >> >> skip the initialization of some virtual queues (vqs). This behavior is
> > >> >> unique to this part of the codebase. In an upcoming commit, we plan to
> > >> >> eliminate this dependency by removing the function entirely. Therefore,
> > >> >> with this change, we are ensuring that the virtio_balloon no longer
> > >> >> depends on the aforementioned function.
> > >> >
> > >> > This is a behavior change, and I believe means that the driver no
> > >> > longer follows the spec [1].
> > >> >
> > >> > For example, the spec says that virtqueue 4 is reporting_vq, and
> > >> > reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
> > >> > but there is no mention of its virtqueue number changing if other
> > >> > features are not set. If a device/driver combination negotiates
> > >> > VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
> > >> > VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
> > >> > that reporting_vq should still be vq number 4, and vq 2 and 3 should
> > >> > be unused. This patch would make the reporting_vq use vq 2 instead in
> > >> > this case.
> > >> >
> > >> > If the new behavior is truly intended, then the spec does not match
> > >> > reality, and it would need to be changed first (IMO); however,
> > >> > changing the spec would mean that any devices implemented correctly
> > >> > per the previous spec would now be wrong, so some kind of mechanism
> > >> > for detecting the new behavior would be warranted, e.g. a new
> > >> > non-device-specific virtio feature flag.
> > >> >
> > >> > I have brought this up previously on the virtio-comment list [2], but
> > >> > it did not receive any satisfying answers at that time.
> >
> > I had missed it back then, but now that I read it, I realize that we
> > really have a bit of a mess here :/
> >
> > >>
> > >> Rings a bell, but staring at this patch, I thought that there would be
> > >> no behavioral change. Maybe I missed it :/
> > >>
> > >> I stared at virtio_ccw_find_vqs(), and it contains:
> > >>
> > >>      for (i = 0; i < nvqs; ++i) {
> > >>              if (!names[i]) {
> > >>                      vqs[i] = NULL;
> > >>                      continue;
> > >>              }
> > >>
> > >>              vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
> > >>                                           names[i], ctx ? ctx[i] : false,
> > >>                                           ccw);
> > >>              if (IS_ERR(vqs[i])) {
> > >>                      ret = PTR_ERR(vqs[i]);
> > >>                      vqs[i] = NULL;
> > >>                      goto out;
> > >>              }
> > >>      }
> > >>
> > >> We increment queue_idx only if an entry was not NULL. SO I thought no
> > >> behavioral change? (at least on s390x :) )
> >
> > The code for pci behaves in the same way.
> >
> > >>
> > >> It's late here in Germany, so maybe I'm missing something.
> > >
> > > I think we've encountered a tricky issue. Currently, all transports handle queue
> > > id by incrementing them in order, without skipping any queue id. So, I'm quite
> > > surprised that my changes would affect the spec. The fact that the
> > > 'names' value is null is just a small trick in the Linux kernel implementation
> > > and should not have an impact on the queue id.
> > >
> > > I believe that my recent modification will not affect the spec. So, let's
> > > consider the issues with this patch set separately for now. Regarding the Memory
> > > Balloon Device, it has been operational for many years, and perhaps we should
> > > add to the spec that if a certain vq does not exist, then subsequent vqs will
> > > take over its id.
> >
> > The changes here do not really seem to affect the spec issue that Daniel
> > had noted, unless I'm reading the code wrong.
>
> Spec seems to be wrong here:
>
> 5.5.2 Virtqueues
>
> 0 inflateq 1 deflateq 2 statsq 3 free_page_vq4 r eporting_vq
>
> And this is the Qemu implementation:
>
> 5.5.2 Virtqueues
>
>     s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
>     s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
>     s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);
>
>     if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
>         s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE,
>                                            virtio_balloon_handle_free_page_vq);
>         precopy_add_notifier(&s->free_page_hint_notify);
>
>         object_ref(OBJECT(s->iothread));
>         s->free_page_bh =
> aio_bh_new_guarded(iothread_get_aio_context(s->iothread),
>
> virtio_ballloon_get_free_page_hints, s,
>                                              &dev->mem_reentrancy_guard);
>     }
>
>     if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) {
>         s->reporting_vq = virtio_add_queue(vdev, 32,
>                                            virtio_balloon_handle_report);
>     }
>
> We need to fix it.

Another possible issue:

FS device:

5.11.2 Virtqueues

0 hiprio 1 notification queue 2…n request queues

The notification queue only exists if VIRTIO_FS_F_NOTIFICATION is set.

Kernel driver had this:

enum {
        VQ_HIPRIO,
        VQ_REQUEST
};

Which means request starts from 1.

Thanks

>
> >
> > However, we should try to address the spec mess, where we have at least
> > some of the most popular/important implementations behaving differently
> > than the spec describes... I would suggest to discuss that on the virtio
> > lists -- but they are still dead, and at this point I'm just hoping
> > they'll come back eventually :/
> >
>
> Thanks


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null
  2024-03-25  9:11         ` David Hildenbrand
@ 2024-03-26 20:23           ` Daniel Verkamp
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Verkamp @ 2024-03-26 20:23 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Xuan Zhuo, virtualization, Richard Weinberger, Anton Ivanov,
	Johannes Berg, Hans de Goede, Ilpo Järvinen,
	Vadim Pasternak, Bjorn Andersson, Mathieu Poirier, Cornelia Huck,
	Halil Pasic, Eric Farman, Heiko Carstens, Vasily Gorbik,
	Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
	Michael S. Tsirkin, Jason Wang, linux-um, platform-driver-x86,
	linux-remoteproc, linux-s390, kvm

On Mon, Mar 25, 2024 at 2:11 AM David Hildenbrand <david@redhat.com> wrote:
>
> On 25.03.24 07:08, Xuan Zhuo wrote:
> > On Fri, 22 Mar 2024 22:02:27 +0100, David Hildenbrand <david@redhat.com> wrote:
> >> On 22.03.24 20:16, Daniel Verkamp wrote:
> >>> On Thu, Mar 21, 2024 at 3:16 AM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >>>>
> >>>> Currently, the init_vqs function within the virtio_balloon driver relies
> >>>> on the condition that certain names array entries are null in order to
> >>>> skip the initialization of some virtual queues (vqs). This behavior is
> >>>> unique to this part of the codebase. In an upcoming commit, we plan to
> >>>> eliminate this dependency by removing the function entirely. Therefore,
> >>>> with this change, we are ensuring that the virtio_balloon no longer
> >>>> depends on the aforementioned function.
> >>>
> >>> This is a behavior change, and I believe means that the driver no
> >>> longer follows the spec [1].
> >>>
> >>> For example, the spec says that virtqueue 4 is reporting_vq, and
> >>> reporting_vq only exists if VIRTIO_BALLOON_F_PAGE_REPORTING is set,
> >>> but there is no mention of its virtqueue number changing if other
> >>> features are not set. If a device/driver combination negotiates
> >>> VIRTIO_BALLOON_F_PAGE_REPORTING but not VIRTIO_BALLOON_F_STATS_VQ or
> >>> VIRTIO_BALLOON_F_FREE_PAGE_HINT, my reading of the specification is
> >>> that reporting_vq should still be vq number 4, and vq 2 and 3 should
> >>> be unused. This patch would make the reporting_vq use vq 2 instead in
> >>> this case.
> >>>
> >>> If the new behavior is truly intended, then the spec does not match
> >>> reality, and it would need to be changed first (IMO); however,
> >>> changing the spec would mean that any devices implemented correctly
> >>> per the previous spec would now be wrong, so some kind of mechanism
> >>> for detecting the new behavior would be warranted, e.g. a new
> >>> non-device-specific virtio feature flag.
> >>>
> >>> I have brought this up previously on the virtio-comment list [2], but
> >>> it did not receive any satisfying answers at that time.
> >>
> >> Rings a bell, but staring at this patch, I thought that there would be
> >> no behavioral change. Maybe I missed it :/
> >>
> >> I stared at virtio_ccw_find_vqs(), and it contains:
> >>
> >>      for (i = 0; i < nvqs; ++i) {
> >>              if (!names[i]) {
> >>                      vqs[i] = NULL;
> >>                      continue;
> >>              }
> >>
> >>              vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i],
> >>                                           names[i], ctx ? ctx[i] : false,
> >>                                           ccw);
> >>              if (IS_ERR(vqs[i])) {
> >>                      ret = PTR_ERR(vqs[i]);
> >>                      vqs[i] = NULL;
> >>                      goto out;
> >>              }
> >>      }
> >>
> >> We increment queue_idx only if an entry was not NULL. SO I thought no
> >> behavioral change? (at least on s390x :) )
> >>
> >> It's late here in Germany, so maybe I'm missing something.
> >
> > I think we've encountered a tricky issue. Currently, all transports handle queue
> > id by incrementing them in order, without skipping any queue id. So, I'm quite
> > surprised that my changes would affect the spec. The fact that the
> > 'names' value is null is just a small trick in the Linux kernel implementation
> > and should not have an impact on the queue id.
> >
> > I believe that my recent modification will not affect the spec. So, let's
> > consider the issues with this patch set separately for now. Regarding the Memory
> > Balloon Device, it has been operational for many years, and perhaps we should
> > add to the spec that if a certain vq does not exist, then subsequent vqs will
> > take over its id.
>
> Right, if I am not missing something your patch should have no
> functional change in that regard (that the current
> behavior/implementation might not match the spec is a different discussion).
>
> @Daniel, if I'm missing something, please shout.

Thanks for digging into that - I think you're correct in that the
patch does not change the behavior, due to changes elsewhere in the
generic virtio and virtio-pci code. So in that sense, I guess this
should not block this particular patch.

It would be good to have the spec situation cleared up, though - I
guess in practice, all relevant drivers and device implementations are
already following the model where there are no gaps in the queue
numbering, rather than what the spec seems to indicate.

Thanks,
-- Daniel

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-03-26 20:24 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-21 10:15 [PATCH vhost v4 0/6] refactor the params of find_vqs() Xuan Zhuo
2024-03-21 10:15 ` [PATCH vhost v4 1/6] virtio_balloon: remove the dependence where names[] is null Xuan Zhuo
2024-03-22 11:56   ` David Hildenbrand
2024-03-25  6:03     ` Xuan Zhuo
2024-03-22 19:16   ` Daniel Verkamp
2024-03-22 21:02     ` David Hildenbrand
2024-03-25  6:08       ` Xuan Zhuo
2024-03-25  9:11         ` David Hildenbrand
2024-03-26 20:23           ` Daniel Verkamp
2024-03-25  9:44         ` Cornelia Huck
2024-03-26  4:11           ` Jason Wang
2024-03-26  4:25             ` Jason Wang
2024-03-21 10:15 ` [PATCH vhost v4 2/6] virtio: remove support for names array entries being null Xuan Zhuo
2024-03-21 10:15 ` [PATCH vhost v4 3/6] virtio: find_vqs: pass struct instead of multi parameters Xuan Zhuo
2024-03-22 14:10   ` kernel test robot
2024-03-23  0:29   ` kernel test robot
2024-03-21 10:15 ` [PATCH vhost v4 4/6] virtio: vring_create_virtqueue: " Xuan Zhuo
2024-03-21 10:15 ` [PATCH vhost v4 5/6] virtio: vring_new_virtqueue(): " Xuan Zhuo
2024-03-21 10:15 ` [PATCH vhost v4 6/6] virtio_ring: simplify the parameters of the funcs related to vring_create/new_virtqueue() Xuan Zhuo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.