From patchwork Wed Mar 6 11:46:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13583984 Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0718780027; Wed, 6 Mar 2024 11:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725590; cv=none; b=tveHHEAYnpJzRnYysYfRrtACRXkxICZ0056auXXbFAfn8lDv2NO3McaNJw/s6QDOv+7bDGWvl8q1lQM2hNwhMglqknPCposCqcKqROrbAfi9+DdRoJA2OZTP03x64ECOooA7k/BS7T9fXstznBOcAh9C95a80B+Clm5uYwU83lo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725590; c=relaxed/simple; bh=t5EJZ/HRztgTJDm02fSGEfBJVxDcEU9wcLzYFgKVgsM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FCfkW2TbKB7vP2+UJoO+FwFOKYpPDnx3rN7kU2QWklLfXCLhQ8eZdeIReRF1Ngf7A4P/axpA4nvcv2/zU6cRAR4YvAXLZXYL7Exjbr7q29+ZseeYgKHxV9XdVov6Abu564vZwOmQ7SfFat+pgNU9Ot24QimG08kNkOBEw8zkOKs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=qDxukckQ; arc=none smtp.client-ip=115.124.30.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="qDxukckQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709725579; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=d5yQXG9mqUunSbrlRRrTtyxK795RLWdeuj4swAGcrNI=; b=qDxukckQpb5csu6SxTlRon/3IR/oRgsx1DNsdnf24i0fFh6Z8GMF/IezZU+mH4E1AMGdPLFIR1xPiHFe/hIhjdJoyttBhrDp9Ox0BNNb0rSBqNEl4J7fARMk2QGGUpTZBx3XtZLzkPiNYXU4RpDgdYnjEScoPrAj4K9f0lhQ7C4= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R161e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045170;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=25;SR=0;TI=SMTPD_---0W1xQCsR_1709725577; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1xQCsR_1709725577) by smtp.aliyun-inc.com; Wed, 06 Mar 2024 19:46:18 +0800 From: Xuan Zhuo To: virtualization@lists.linux.dev Cc: Richard Weinberger , Anton Ivanov , Johannes Berg , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , 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 , Xuan Zhuo , linux-um@lists.infradead.org, platform-driver-x86@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, kvm@vger.kernel.org Subject: [PATCH vhost v1 1/4] virtio: find_vqs: pass struct instead of multi parameters Date: Wed, 6 Mar 2024 19:46:12 +0800 Message-Id: <20240306114615.88770-2-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> References: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-remoteproc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: b9b03370361a 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. Signed-off-by: Xuan Zhuo Acked-by: Johannes Berg --- arch/um/drivers/virtio_uml.c | 23 +++---- drivers/platform/mellanox/mlxbf-tmfifo.c | 13 ++-- drivers/remoteproc/remoteproc_virtio.c | 28 ++++----- drivers/s390/virtio/virtio_ccw.c | 29 +++++---- drivers/virtio/virtio_mmio.c | 26 ++++---- drivers/virtio/virtio_pci_common.c | 60 +++++++++--------- drivers/virtio/virtio_pci_common.h | 9 +-- drivers/virtio/virtio_pci_legacy.c | 11 ++-- drivers/virtio/virtio_pci_modern.c | 33 ++++++---- drivers/virtio/virtio_vdpa.c | 36 +++++------ include/linux/virtio_config.h | 77 +++++++++++++++++++----- 11 files changed, 192 insertions(+), 153 deletions(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 8adca2000e51..c13dfeeb90c4 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[cfg->cfg_idx]); vq = vring_create_virtqueue(index, num, PAGE_SIZE, vdev, true, true, - ctx, vu_notify, callback, info->name); + cfg->ctx ? cfg->ctx[cfg->cfg_idx] : false, + vu_notify, + cfg->callbacks[cfg->cfg_idx], 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,13 +1032,13 @@ static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs, return rc; for (i = 0; i < nvqs; ++i) { - if (!names[i]) { + if (!cfg->names[i]) { vqs[i] = NULL; continue; } - vqs[i] = vu_setup_vq(vdev, queue_idx++, callbacks[i], names[i], - ctx ? ctx[i] : false); + cfg->cfg_idx = i; + 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 b8d1e32e97eb..4252388f52a2 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; @@ -1072,7 +1069,7 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct virtio_device *vdev, return -EINVAL; for (i = 0; i < nvqs; ++i) { - if (!names[i]) { + if (!cfg->names[i]) { ret = -EINVAL; goto error; } @@ -1084,7 +1081,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 83d76915a6ad..57d51c9c7b63 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,7 +118,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, if (id >= ARRAY_SIZE(rvdev->vring)) return ERR_PTR(-EINVAL); - if (!name) + if (!cfg->names[cfg->cfg_idx]) return NULL; /* Search allocated memory region by name */ @@ -143,10 +142,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[cfg->cfg_idx] : false, + addr, rproc_virtio_notify, cfg->callbacks[cfg->cfg_idx], + cfg->names[cfg->cfg_idx]); if (!vq) { - dev_err(dev, "vring_new_virtqueue %s failed\n", name); + dev_err(dev, "vring_new_virtqueue %s failed\n", cfg->names[cfg->cfg_idx]); rproc_free_vring(rvring); return ERR_PTR(-ENOMEM); } @@ -180,23 +181,20 @@ 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) { - if (!names[i]) { + if (!cfg->names[i]) { vqs[i] = NULL; continue; } - vqs[i] = rp_find_vq(vdev, queue_idx++, callbacks[i], names[i], - ctx ? ctx[i] : false); + cfg->cfg_idx = i; + 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 ac67576301bf..11eea5086cff 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[cfg->cfg_idx] : false, + notify, + cfg->callbacks[cfg->cfg_idx], + cfg->names[cfg->cfg_idx]); 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,14 +667,13 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs, return -ENOMEM; for (i = 0; i < nvqs; ++i) { - if (!names[i]) { + if (!cfg->names[i]) { vqs[i] = NULL; continue; } - vqs[i] = virtio_ccw_setup_vq(vdev, queue_idx++, callbacks[i], - names[i], ctx ? ctx[i] : false, - ccw); + cfg->cfg_idx = i; + 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 59892a31cf76..feb823d279d2 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,7 +385,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in else notify = vm_notify; - if (!name) + if (!cfg->names[index]) return NULL; /* Select the queue we're interested in */ @@ -414,7 +413,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[cfg->cfg_idx] : false, + notify, + cfg->callbacks[cfg->cfg_idx], + cfg->names[cfg->cfg_idx]); if (!vq) { err = -ENOMEM; goto error_new_virtqueue; @@ -487,15 +490,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,13 +510,13 @@ 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]) { + if (!cfg->names[i]) { vqs[i] = NULL; continue; } - vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i], - ctx ? ctx[i] : false); + cfg->cfg_idx = i; + 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 b655fccaf773..775537234b00 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[cfg->cfg_idx]) { 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,27 +307,27 @@ 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 (!names[i]) { + if (!cfg->names[i]) { vqs[i] = NULL; continue; } - 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); + + cfg->cfg_idx = i; + vqs[i] = vp_setup_vq(vdev, queue_idx++, cfg, msix_vec); if (IS_ERR(vqs[i])) { err = PTR_ERR(vqs[i]); goto error_find; @@ -343,7 +340,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], @@ -358,11 +355,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); @@ -377,13 +374,13 @@ 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]) { + if (!cfg->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); + + cfg->cfg_idx = i; + 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; @@ -397,26 +394,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..e8d22fce32f5 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[cfg->cfg_idx] : false, + vp_notify, + cfg->callbacks[cfg->cfg_idx], + cfg->names[cfg->cfg_idx]); if (!vq) return ERR_PTR(-ENOMEM); diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index f62b530aa3b5..b2cdf5d3824d 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[cfg->cfg_idx] : false, + notify, + cfg->callbacks[cfg->cfg_idx], + cfg->names[cfg->cfg_idx]); 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,11 @@ 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; + cfg.cfg_idx = 0; + 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 e803db0da307..7f3e173f669c 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,7 +160,7 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index, bool may_reduce_num = true; int err; - if (!name) + if (!cfg->names[cfg->cfg_idx]) return NULL; if (index >= vdpa->nvqs) @@ -206,8 +205,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[cfg->cfg_idx] : false, + notify, + cfg->callbacks[cfg->cfg_idx], + cfg->names[cfg->cfg_idx], + dma_dev); if (!vq) { err = -ENOMEM; goto error_new_virtqueue; @@ -216,7 +219,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 +359,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,24 +368,25 @@ 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) { - if (!names[i]) { + if (!cfg->names[i]) { vqs[i] = NULL; continue; } - vqs[i] = virtio_vdpa_setup_vq(vdev, queue_idx++, - callbacks[i], names[i], ctx ? - ctx[i] : false); + cfg->cfg_idx = i; + 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 da9b271b54db..80a1e3ecbdeb 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -18,6 +18,38 @@ struct virtio_shm_region { typedef void vq_callback_t(struct virtqueue *); +/** + * struct virtio_vq_config - configure for find_vqs() + * @cfg_idx: Used by virtio core. The drivers should set this to 0. + * During the initialization of each vq(vring setup), we need to know which + * item in the array should be used at that time. But since the item in + * names can be null, which causes some item of array to be skipped, we + * cannot use vq.index as the current id. So add a cfg_idx to let vring + * know how to get the current configuration from the array when + * initializing vq. + * @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) + * include a NULL entry for vqs unused by driver + * @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 cfg_idx; + + unsigned int nvqs; + + struct virtqueue **vqs; + vq_callback_t **callbacks; + const char *const *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,12 +83,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) - * include a NULL entry for vqs unused by driver + * 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) @@ -96,6 +123,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); @@ -105,10 +133,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); @@ -217,8 +242,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; @@ -230,7 +261,15 @@ int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, 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 = names; + cfg.desc = desc; + + return vdev->config->find_vqs(vdev, &cfg); } static inline @@ -239,8 +278,16 @@ int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs, const char * const 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); } /** From patchwork Wed Mar 6 11:46:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13583982 Received: from out30-130.freemail.mail.aliyun.com (out30-130.freemail.mail.aliyun.com [115.124.30.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C24C7FBA0; Wed, 6 Mar 2024 11:46:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725585; cv=none; b=sjI0Yz+HqRPsyf00oEG8KP+E6znltRL3HPDxYIluUH8rwNoddTul0ivHb21F18mEOGKuTFAan9htmPkbaqDxuLj1nIP19BEaGVpvvY17eKsvKNWKGCS3XQMtnYAcYNiYiejJ/qfsWuqhQGY5FgxNj+tOJ6EoQ2wEmzQip12efmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725585; c=relaxed/simple; bh=ZymX2ZYETu+8JkXIKKUVVlXMNRGURqjMwLa6klx/p9k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cb78wV+HJPyE0Rb5pSRZSJv7b9X7CLRyMWt0onKy4zJz/9JVvEMqA/B9tfFjUxkbOhj1Wq7g4ez91e+gU5Nlb4eA9frjo9gqgP8kZIdUTlSiu+eyXYc/gGTJWGKRzfl/Lh5/S7s9IMmzk0COHQ/4zMZuZJw2Xj1Q62BEUllkjoc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=PCA920Zz; arc=none smtp.client-ip=115.124.30.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="PCA920Zz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709725580; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=B1ArvdFDpgCvpO8WHQUpkUaLMT3WU20rxP77F4IbSYk=; b=PCA920Zzj7XZrLUlRtYoBil574KjE8hfXr5o3XtOQh8A8og7Ziior9XPfU1vHTwORJlHBEwbNMf/od3UXrdsbbkRKL2x2QJ+CQyarLcF5iHkDf+Wb5UxaAOE3P2laVpRbmlx0FTEyDi6BNQnkh0XgsBeRDSNNg6GvzRqHis10o8= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R551e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045168;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=25;SR=0;TI=SMTPD_---0W1xQCt3_1709725578; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1xQCt3_1709725578) by smtp.aliyun-inc.com; Wed, 06 Mar 2024 19:46:19 +0800 From: Xuan Zhuo To: virtualization@lists.linux.dev Cc: Richard Weinberger , Anton Ivanov , Johannes Berg , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , 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 , Xuan Zhuo , linux-um@lists.infradead.org, platform-driver-x86@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, kvm@vger.kernel.org Subject: [PATCH vhost v1 2/4] virtio: vring_create_virtqueue: pass struct instead of multi parameters Date: Wed, 6 Mar 2024 19:46:13 +0800 Message-Id: <20240306114615.88770-3-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> References: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-remoteproc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: b9b03370361a 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. Because the virtio_uml.c changes the name, so change the "names" inside the virtio_vq_config from "const char *const *names" to "const char **names". Signed-off-by: Xuan Zhuo Acked-by: Johannes Berg --- 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_config.h | 6 ++-- include/linux/virtio_ring.h | 40 ++++++++------------- 9 files changed, 93 insertions(+), 103 deletions(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index c13dfeeb90c4..1c2d59d3d02b 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[cfg->cfg_idx]); - vq = vring_create_virtqueue(index, num, PAGE_SIZE, vdev, true, true, - cfg->ctx ? cfg->ctx[cfg->cfg_idx] : false, - vu_notify, - cfg->callbacks[cfg->cfg_idx], 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[cfg->cfg_idx] = 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 11eea5086cff..f8d5bbd13359 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[cfg->cfg_idx] : false, - notify, - cfg->callbacks[cfg->cfg_idx], - cfg->names[cfg->cfg_idx]); + 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 feb823d279d2..cb172fa4d7cc 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; @@ -411,13 +412,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[cfg->cfg_idx] : false, - notify, - cfg->callbacks[cfg->cfg_idx], - cfg->names[cfg->cfg_idx]); + 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 e8d22fce32f5..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[cfg->cfg_idx] : false, - vp_notify, - cfg->callbacks[cfg->cfg_idx], - cfg->names[cfg->cfg_idx]); + 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 b2cdf5d3824d..dd75534346d1 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[cfg->cfg_idx] : false, - notify, - cfg->callbacks[cfg->cfg_idx], - cfg->names[cfg->cfg_idx]); + 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..08858e2d761e 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[cfg->cfg_idx]; + callback = cfg->callbacks[cfg->cfg_idx]; + context = cfg->ctx ? cfg->ctx[cfg->cfg_idx] : 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 7f3e173f669c..1ab219fce653 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; @@ -201,16 +201,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[cfg->cfg_idx] : false, - notify, - cfg->callbacks[cfg->cfg_idx], - cfg->names[cfg->cfg_idx], - 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_config.h b/include/linux/virtio_config.h index 80a1e3ecbdeb..f79e7e9be512 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -45,7 +45,7 @@ struct virtio_vq_config { struct virtqueue **vqs; vq_callback_t **callbacks; - const char *const *names; + const char **names; const bool *ctx; struct irq_affinity *desc; }; @@ -266,7 +266,7 @@ int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, cfg.nvqs = nvqs; cfg.vqs = vqs; cfg.callbacks = callbacks; - cfg.names = names; + cfg.names = (const char **)names; cfg.desc = desc; return vdev->config->find_vqs(vdev, &cfg); @@ -283,7 +283,7 @@ int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs, cfg.nvqs = nvqs; cfg.vqs = vqs; cfg.callbacks = callbacks; - cfg.names = names; + cfg.names = (const char **)names; cfg.ctx = ctx; cfg.desc = desc; diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index 9b33df741b63..cd8042c79814 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -5,6 +5,7 @@ #include #include #include +#include /* * Barriers in virtio are tricky. Non-SMP virtio guests can't assume @@ -60,38 +61,25 @@ struct virtio_device; struct virtqueue; struct device; +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 From patchwork Wed Mar 6 11:46:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13583985 Received: from out30-119.freemail.mail.aliyun.com (out30-119.freemail.mail.aliyun.com [115.124.30.119]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9E9F80032; Wed, 6 Mar 2024 11:46:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.119 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725593; cv=none; b=ej6P8DX5dg/Wmhekww/nlaHIgMlvqsXkrlLTKjhyBu8X0j+2IR/0Uid0EbPHYOgys2hTz6X/E04t5KdCY5fuBezhBvZ/qZLSVrXALECYN0no5OlWRyVFaK3pqTaqKXUsAa3PKPHL7L7uLermZIdoTbgvwEiZtM5i4y5nJt2yfR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725593; c=relaxed/simple; bh=LnAnyCNs0kL8YdCiNfUHcciNm/48j5cRld4S6QPKdVA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XPss52Sqa487DsEHE8OpxbLW7sF6qN72Xju6CXIlb6HhXYwAevYmTXxYLcqFxrQQ/BR4SlvGkitIq5FZH6I4SVW/XihTwcgVNyfo+r8OIG/3W9fb6tVYg7ZHNXXbCSrwYpopmraCK6DqsYEFKo8wButUa56GBlWgLg0beTgrGvo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=fQXRNtXm; arc=none smtp.client-ip=115.124.30.119 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="fQXRNtXm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709725582; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=20WVxU0ax3G4Q5U1M/0J3sL6D4ujW6bHGT2WAA1P+9I=; b=fQXRNtXmifCcRloUlcGLAmLtx5siMszuIegEWB4V2TP4mtdHqe4Me6JzgsS3mzQL3CjKA27wQph6nXc/64fpDxtiZ5B2Mul0fYFuMru55BqESE3qNEIgMPCWcQfViCDANxk4Uo4iPB9Pvj79yGHo4TiA853lr1nNGhaYRhZQZSQ= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R351e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046049;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=25;SR=0;TI=SMTPD_---0W1xTXdF_1709725579; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1xTXdF_1709725579) by smtp.aliyun-inc.com; Wed, 06 Mar 2024 19:46:20 +0800 From: Xuan Zhuo To: virtualization@lists.linux.dev Cc: Richard Weinberger , Anton Ivanov , Johannes Berg , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , 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 , Xuan Zhuo , linux-um@lists.infradead.org, platform-driver-x86@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, kvm@vger.kernel.org Subject: [PATCH vhost v1 3/4] virtio: vring_new_virtqueue(): pass struct instead of multi parameters Date: Wed, 6 Mar 2024 19:46:14 +0800 Message-Id: <20240306114615.88770-4-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> References: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-remoteproc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: b9b03370361a 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 --- drivers/platform/mellanox/mlxbf-tmfifo.c | 13 +++++--- 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, 85 insertions(+), 42 deletions(-) diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c index 4252388f52a2..36cfce5ba8cf 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; @@ -1078,10 +1079,14 @@ 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; + + cfg->cfg_idx = i; + 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 57d51c9c7b63..70c32837f9dc 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; @@ -138,14 +139,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[cfg->cfg_idx] : false, - addr, rproc_virtio_notify, cfg->callbacks[cfg->cfg_idx], - cfg->names[cfg->cfg_idx]); + vq = vring_new_virtqueue(vdev, id, addr, &tp_cfg, cfg); if (!vq) { dev_err(dev, "vring_new_virtqueue %s failed\n", cfg->names[cfg->cfg_idx]); rproc_free_vring(rvring); diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 08858e2d761e..03687800d8ff 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[cfg->cfg_idx]; + callback = cfg->callbacks[cfg->cfg_idx]; + context = cfg->ctx ? cfg->ctx[cfg->cfg_idx] : 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 cd8042c79814..616937780785 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -85,16 +85,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); From patchwork Wed Mar 6 11:46:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13583983 Received: from out30-97.freemail.mail.aliyun.com (out30-97.freemail.mail.aliyun.com [115.124.30.97]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56CB37FBA0; Wed, 6 Mar 2024 11:46:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.97 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725590; cv=none; b=iFLyX36OiUYN4jkGt/yYl6mWtshr+i21UD5it/JidVUk8dcV/Jrcdirsu+oP7x5YxnlYTWYstgjMaaIWrpzdYFJzIsAxiKCOwAQY/veVV3T04/dzwUocHA0eujrfR7pVufqRfqhJul7KCspPg17axRx0i6KnghwQgVCQRJOGXLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709725590; c=relaxed/simple; bh=mnfECoRhxOUr5hq+aTQH146GAEbMcFSwTqK664QF1ug=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eLVK3coT3xs4ZUhY6wLREJgTbTuM+Lo/0w2RzZhrEiXspV8eYm6NrK5ZQANzH/qJfU/Q/OrY++74vHmxVcucF/J6nzi4mbMSAPbO/nZVB5BTrpbDXUkJxMSaDVvyDp8B86OZ+8gUTyZ66g5Y+hXEKX6QxuqZ7OH3Tb++zOMcG28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=fQ31P48E; arc=none smtp.client-ip=115.124.30.97 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="fQ31P48E" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709725583; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=kjSYAVfiWOD4MW886BySgZ+l1WsXmtRdOaa62X5lOi4=; b=fQ31P48ErJO6UStAokXkcAqAKDp7NVlNbpOUBLKQkd1DJ5rS8e8Li2/6bSWmqHvUbG4tYEW2VBZBgInPJnKRe2fNYWxisgafVg75Z4Q1WTAoiXfh9G8veDb8+BNiulgJzt3SMsa+VDiqgqvtOm5rTsmM9ymempQyWXBshPV6Uc4= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045170;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=25;SR=0;TI=SMTPD_---0W1xRjNA_1709725581; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1xRjNA_1709725581) by smtp.aliyun-inc.com; Wed, 06 Mar 2024 19:46:22 +0800 From: Xuan Zhuo To: virtualization@lists.linux.dev Cc: Richard Weinberger , Anton Ivanov , Johannes Berg , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , 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 , Xuan Zhuo , linux-um@lists.infradead.org, platform-driver-x86@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, kvm@vger.kernel.org Subject: [PATCH vhost v1 4/4] virtio_ring: simplify the parameters of the funcs related to vring_create/new_virtqueue() Date: Wed, 6 Mar 2024 19:46:15 +0800 Message-Id: <20240306114615.88770-5-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> References: <20240306114615.88770-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: linux-remoteproc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: b9b03370361a 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 --- 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 03687800d8ff..94c442ba844f 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, key) (cfg->key[cfg->cfg_idx]) +#define cfg_vq_get(cfg, key) (cfg->key ? cfg_vq_val(cfg, 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, callbacks); vq->vq.vdev = vdev; - vq->vq.name = name; + vq->vq.name = cfg_vq_val(cfg, 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, 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, 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, callbacks); vq->vq.vdev = vdev; - vq->vq.name = name; + vq->vq.name = cfg_vq_val(cfg, 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, 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[cfg->cfg_idx]; - callback = cfg->callbacks[cfg->cfg_idx]; - context = cfg->ctx ? cfg->ctx[cfg->cfg_idx] : 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[cfg->cfg_idx]; - callback = cfg->callbacks[cfg->cfg_idx]; - context = cfg->ctx ? cfg->ctx[cfg->cfg_idx] : 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);