[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220704171701.127665-7-sgarzare@redhat.com>
Date: Mon, 4 Jul 2022 19:17:01 +0200
From: Stefano Garzarella <sgarzare@...hat.com>
To: virtualization@...ts.linux-foundation.org
Cc: Jason Wang <jasowang@...hat.com>,
"Michael S. Tsirkin" <mst@...hat.com>,
linux-kernel@...r.kernel.org,
Eugenio PĂ©rez <eperezma@...hat.com>,
Stefano Garzarella <sgarzare@...hat.com>
Subject: [RFC PATCH 6/6] vdpasim: add vdpa_sim_test module
This adds a test module for vhost-vdpa infrastructure to be used
with virtio_test.
Intentionally not tied to kbuild to prevent people from installing
and loading it accidentally.
Signed-off-by: Stefano Garzarella <sgarzare@...hat.com>
---
drivers/vdpa/vdpa_sim/vdpa_sim_test.c | 203 ++++++++++++++++++++++++++
tools/virtio/vdpa_test/vdpa_test.c | 1 +
tools/virtio/Makefile | 32 +++-
tools/virtio/vdpa_test/Makefile | 3 +
4 files changed, 234 insertions(+), 5 deletions(-)
create mode 100644 drivers/vdpa/vdpa_sim/vdpa_sim_test.c
create mode 100644 tools/virtio/vdpa_test/vdpa_test.c
create mode 100644 tools/virtio/vdpa_test/Makefile
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_test.c b/drivers/vdpa/vdpa_sim/vdpa_sim_test.c
new file mode 100644
index 000000000000..17628b1a1cdd
--- /dev/null
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_test.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * VDPA simulator for virtio-test.
+ *
+ * Copyright (c) 2022, Red Hat Inc. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/vringh.h>
+#include <linux/vdpa.h>
+
+#include "vdpa_sim.h"
+
+#define DRV_VERSION "0.1"
+#define DRV_AUTHOR "Stefano Garzarella <sgarzare@...hat.com>"
+#define DRV_DESC "vDPA Device Simulator for virtio-test device"
+#define DRV_LICENSE "GPL v2"
+
+#define VDPASIM_TEST_FEATURES (VDPASIM_FEATURES)
+#define VDPASIM_TEST_VIRTIO_ID 0
+
+/* 1 virtqueues, 1 address spaces, 1 virtqueue groups */
+#define VDPASIM_TEST_VQ_NUM 1
+#define VDPASIM_TEST_AS_NUM 1
+#define VDPASIM_TEST_GROUP_NUM 1
+
+static bool vdpasim_test_handle_req(struct vdpasim *vdpasim,
+ struct vdpasim_virtqueue *vq)
+{
+ int ret;
+
+ ret = vringh_getdesc_iotlb(&vq->vring, &vq->out_iov, &vq->in_iov,
+ &vq->head, GFP_ATOMIC);
+ if (ret != 1)
+ return false;
+
+ if (vq->out_iov.used == 0 || vq->in_iov.used > 0) {
+ dev_dbg(&vdpasim->vdpa.dev, "Unexpected descriptor format - out_iov: %u in_iov %u\n",
+ vq->out_iov.used, vq->in_iov.used);
+ return false;
+ }
+
+ if (vringh_kiov_length(&vq->out_iov) == 0) {
+ dev_dbg(&vdpasim->vdpa.dev, "Unexpected 0 len for out buffer\n");
+ return false;
+ }
+
+ vringh_complete_iotlb(&vq->vring, vq->head, 0);
+
+ return true;
+}
+
+static void vdpasim_test_work(struct work_struct *work)
+{
+ struct vdpasim *vdpasim = container_of(work, struct vdpasim, work);
+ bool reschedule = false;
+ int i;
+
+ spin_lock(&vdpasim->lock);
+
+ if (!(vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK))
+ goto out;
+
+ for (i = 0; i < VDPASIM_TEST_VQ_NUM; i++) {
+ struct vdpasim_virtqueue *vq = &vdpasim->vqs[i];
+ int reqs = 0;
+
+ if (!vq->ready)
+ continue;
+
+ while (vdpasim_test_handle_req(vdpasim, vq)) {
+ /* Make sure used is visible before rasing the interrupt. */
+ smp_wmb();
+
+ local_bh_disable();
+ if (vringh_need_notify_iotlb(&vq->vring) > 0)
+ vringh_notify(&vq->vring);
+ local_bh_enable();
+
+ if (++reqs > 4) {
+ reschedule = true;
+ break;
+ }
+ }
+ }
+out:
+ spin_unlock(&vdpasim->lock);
+
+ if (reschedule)
+ schedule_work(&vdpasim->work);
+}
+
+static void vdpasim_test_get_config(struct vdpasim *vdpasim, void *config)
+{
+ u64 *test_config = config;
+
+ *test_config = cpu_to_vdpasim64(vdpasim, 42);
+}
+
+static void vdpasim_test_mgmtdev_release(struct device *dev)
+{
+}
+
+static struct device vdpasim_test_mgmtdev = {
+ .init_name = "vdpasim_test",
+ .release = vdpasim_test_mgmtdev_release,
+};
+
+static int vdpasim_test_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
+ const struct vdpa_dev_set_config *config)
+{
+ struct vdpasim_dev_attr dev_attr = {};
+ struct vdpasim *simdev;
+ int ret;
+
+ dev_attr.mgmt_dev = mdev;
+ dev_attr.name = name;
+ dev_attr.id = VDPASIM_TEST_VIRTIO_ID;
+ dev_attr.supported_features = VDPASIM_TEST_FEATURES;
+ dev_attr.nvqs = VDPASIM_TEST_VQ_NUM;
+ dev_attr.ngroups = VDPASIM_TEST_GROUP_NUM;
+ dev_attr.nas = VDPASIM_TEST_AS_NUM;
+ dev_attr.config_size = sizeof(uint64_t);
+ dev_attr.get_config = vdpasim_test_get_config;
+ dev_attr.work_fn = vdpasim_test_work;
+ dev_attr.buffer_size = 0;
+
+ simdev = vdpasim_create(&dev_attr);
+ if (IS_ERR(simdev))
+ return PTR_ERR(simdev);
+
+ ret = _vdpa_register_device(&simdev->vdpa, VDPASIM_TEST_VQ_NUM);
+ if (ret)
+ goto put_dev;
+
+ return 0;
+
+put_dev:
+ put_device(&simdev->vdpa.dev);
+ return ret;
+}
+
+static void vdpasim_test_dev_del(struct vdpa_mgmt_dev *mdev,
+ struct vdpa_device *dev)
+{
+ struct vdpasim *simdev = container_of(dev, struct vdpasim, vdpa);
+
+ _vdpa_unregister_device(&simdev->vdpa);
+}
+
+static const struct vdpa_mgmtdev_ops vdpasim_test_mgmtdev_ops = {
+ .dev_add = vdpasim_test_dev_add,
+ .dev_del = vdpasim_test_dev_del
+};
+
+static struct virtio_device_id id_table[] = {
+ { VDPASIM_TEST_VIRTIO_ID, VIRTIO_DEV_ANY_ID },
+ { 0 },
+};
+
+static struct vdpa_mgmt_dev mgmt_dev = {
+ .device = &vdpasim_test_mgmtdev,
+ .id_table = id_table,
+ .ops = &vdpasim_test_mgmtdev_ops,
+};
+
+static int __init vdpasim_test_init(void)
+{
+ int ret;
+
+ ret = device_register(&vdpasim_test_mgmtdev);
+ if (ret)
+ return ret;
+
+ ret = vdpa_mgmtdev_register(&mgmt_dev);
+ if (ret)
+ goto parent_err;
+
+ return 0;
+
+parent_err:
+ device_unregister(&vdpasim_test_mgmtdev);
+ return ret;
+}
+
+static void __exit vdpasim_test_exit(void)
+{
+ vdpa_mgmtdev_unregister(&mgmt_dev);
+ device_unregister(&vdpasim_test_mgmtdev);
+}
+
+module_init(vdpasim_test_init)
+module_exit(vdpasim_test_exit)
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE(DRV_LICENSE);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
diff --git a/tools/virtio/vdpa_test/vdpa_test.c b/tools/virtio/vdpa_test/vdpa_test.c
new file mode 100644
index 000000000000..779d2be2c9e5
--- /dev/null
+++ b/tools/virtio/vdpa_test/vdpa_test.c
@@ -0,0 +1 @@
+#include "vdpa_sim/vdpa_sim_test.c"
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
index 1b25cc7c64bb..74a3e8d649a3 100644
--- a/tools/virtio/Makefile
+++ b/tools/virtio/Makefile
@@ -10,6 +10,7 @@ LDFLAGS += -pthread
vpath %.c ../../drivers/virtio ../../drivers/vhost
mod:
${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V}
+ ${MAKE} -C `pwd`/../.. M=`pwd`/vdpa_test V=${V}
#oot: build vhost as an out of tree module for a distro kernel
#no effort is taken to make it actually build or work, but tends to mostly work
@@ -18,26 +19,47 @@ mod:
#resulting modules in production!
OOT_KSRC=/lib/modules/$$(uname -r)/build
OOT_VHOST=`pwd`/../../drivers/vhost
+OOT_VDPA=`pwd`/../../drivers/vdpa
#Everyone depends on vhost
#Tweak the below to enable more modules
OOT_CONFIGS=\
CONFIG_VHOST=m \
+ CONFIG_VHOST_VDPA=m \
CONFIG_VHOST_NET=n \
CONFIG_VHOST_SCSI=n \
CONFIG_VHOST_VSOCK=n \
CONFIG_VHOST_RING=n
-OOT_BUILD=KCFLAGS="-I "${OOT_VHOST} ${MAKE} -C ${OOT_KSRC} V=${V}
+OOT_VDPA_CONFIGS=\
+ CONFIG_VDPA=m \
+ CONFIG_VDPA_SIM=m \
+ CONFIG_VDPA_SIM_NET=n \
+ CONFIG_VDPA_SIM_BLOCK=n \
+ CONFIG_VDPA_USER=n \
+ CONFIG_MLX5_VDPA=n \
+ CONFIG_MLX5_VDPA_NET=n \
+ CONFIG_IFCVF=n \
+ CONFIG_VP_VDPA=n \
+ CONFIG_ALIBABA_ENI_VDPA=n
+OOT_BUILD=KCFLAGS="-I "${OOT_VHOST}" -I "${OOT_VDPA} ${MAKE} -C ${OOT_KSRC} V=${V}
oot-build:
echo "UNSUPPORTED! Don't use the resulting modules in production!"
${OOT_BUILD} M=`pwd`/vhost_test
${OOT_BUILD} M=${OOT_VHOST} ${OOT_CONFIGS}
-oot-clean: oot-build
-oot: oot-build
+oot-vdpa-build: oot-build
+ echo "UNSUPPORTED! Don't use the resulting modules in production!"
+ ${OOT_BUILD} M=`pwd`/vdpa_test
+ ${OOT_BUILD} M=${OOT_VDPA} ${OOT_VDPA_CONFIGS}
+
+oot-clean: oot
+oot: oot-build oot-vdpa-build
oot-clean: OOT_BUILD+=clean
-.PHONY: all test mod clean vhost oot oot-clean oot-build
-clean:
+.PHONY: all test mod clean vhost oot oot-clean oot-build oot-vdpa-build clean-vdpa
+clean-vdpa:
+ ${RM} vdpa_test/*.o vdpa_test/.*.cmd vdpa_test/Module.symvers \
+ vdpa_test/modules.order
+clean: clean-vdpa
${RM} *.o vringh_test virtio_test vhost_test/*.o vhost_test/.*.cmd \
vhost_test/Module.symvers vhost_test/modules.order *.d
-include *.d
diff --git a/tools/virtio/vdpa_test/Makefile b/tools/virtio/vdpa_test/Makefile
new file mode 100644
index 000000000000..fce9f344d88f
--- /dev/null
+++ b/tools/virtio/vdpa_test/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-m += vdpa_test.o
+ccflags-y += -I$(srctree)/drivers/vdpa/
--
2.36.1
Powered by blists - more mailing lists