Stefano Garzarella
2022-Jul-04 17:16 UTC
[RFC PATCH 0/6] virtio_test: add support for vhost-vdpa
The first 3 patches fix various problems I have encountered with virtio_test (they may go without this series, but I included to allow you to test the series). Patch 4 is in preparation of patch 5, moving the feature negotiation when we initialize the device. Patch 5 add the support of vhost-vdpa in virtio_test Patch 6 add vdpa_test.ko based on vdpa_sim_test.c, so we can reuse most of the code coming from the vdpa_sim framework. I tested in this way: $ modprobe vdpa_sim $ modprobe vhost-vdpa # load the vdpasim_test device $ insmod vdpa_test.ko # create a new vdpasim_test device $ vdpa dev add mgmtdev vdpasim_test name dev0 # run the test using the /dev/vhost-vdpa-0 device $ ./virtio_test --vdpa /dev/vhost-vdpa-0 spurious wakeups: 0x0 started=0x100000 completed=0x100000 Comments and suggestions are welcome :-) Thanks, Stefano Stefano Garzarella (6): tools/virtio: fix build vhost_test: add $(srctree) on the included path virtio_test: call __virtio_unbreak_device tools/virtio: move feature negotiation in vdev_info_init() virtio_test: support vhost-vdpa device vdpasim: add vdpa_sim_test module tools/virtio/linux/kernel.h | 2 +- tools/virtio/linux/virtio.h | 2 + tools/virtio/linux/vringh.h | 1 + drivers/vdpa/vdpa_sim/vdpa_sim_test.c | 203 ++++++++++++++++++++++++++ tools/virtio/vdpa_test/vdpa_test.c | 1 + tools/virtio/virtio_test.c | 131 ++++++++++++++--- tools/virtio/Makefile | 32 +++- tools/virtio/vdpa_test/Makefile | 3 + tools/virtio/vhost_test/Makefile | 2 +- 9 files changed, 350 insertions(+), 27 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 -- 2.36.1
Fix the build caused by the following changes: - phys_addr_t is now defined in tools/include/linux/types.h - dev_warn_once() is used in drivers/virtio/virtio_ring.c - linux/uio.h included by vringh.h use INT_MAX defined in limits.h Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- tools/virtio/linux/kernel.h | 2 +- tools/virtio/linux/vringh.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/virtio/linux/kernel.h b/tools/virtio/linux/kernel.h index 0b493542e61a..21593bf97755 100644 --- a/tools/virtio/linux/kernel.h +++ b/tools/virtio/linux/kernel.h @@ -29,7 +29,6 @@ #define READ 0 #define WRITE 1 -typedef unsigned long long phys_addr_t; typedef unsigned long long dma_addr_t; typedef size_t __kernel_size_t; typedef unsigned int __wsum; @@ -136,6 +135,7 @@ static inline void *krealloc_array(void *p, size_t new_n, size_t new_size, gfp_t #endif #define dev_err(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) #define dev_warn(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) +#define dev_warn_once(dev, format, ...) fprintf (stderr, format, ## __VA_ARGS__) #define min(x, y) ({ \ typeof(x) _min1 = (x); \ diff --git a/tools/virtio/linux/vringh.h b/tools/virtio/linux/vringh.h index 9348957be56e..e11c6aece734 100644 --- a/tools/virtio/linux/vringh.h +++ b/tools/virtio/linux/vringh.h @@ -1 +1,2 @@ +#include <limits.h> #include "../../../include/linux/vringh.h" -- 2.36.1
Stefano Garzarella
2022-Jul-04 17:16 UTC
[RFC PATCH 2/6] vhost_test: add $(srctree) on the included path
Adding $(srctree) on the included path we can build vhost_test also when the kernel is not built in the source tree (make O=...). Use of EXTRA_CFLAGS is deprecated, so let's use ccflags-y. Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- tools/virtio/vhost_test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/virtio/vhost_test/Makefile b/tools/virtio/vhost_test/Makefile index 94d3aff987dc..df5ad39e2520 100644 --- a/tools/virtio/vhost_test/Makefile +++ b/tools/virtio/vhost_test/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-m += vhost_test.o -EXTRA_CFLAGS += -Idrivers/vhost +ccflags-y += -I$(srctree)/drivers/vhost -- 2.36.1
Stefano Garzarella
2022-Jul-04 17:16 UTC
[RFC PATCH 3/6] virtio_test: call __virtio_unbreak_device
Commit 8b4ec69d7e09 ("virtio: harden vring IRQ") initialize vq->broken to true, so we need to call __virtio_unbreak_device() before starting to use it. Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- tools/virtio/linux/virtio.h | 2 ++ tools/virtio/virtio_test.c | 1 + 2 files changed, 3 insertions(+) diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index 363b98228301..feb720d4304f 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h @@ -66,4 +66,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, const char *name); void vring_del_virtqueue(struct virtqueue *vq); +void __virtio_unbreak_device(struct virtio_device *dev); + #endif diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 23f142af544a..765e64895dab 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -177,6 +177,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, long long spurious = 0; const bool random_batch = batch == RANDOM_BATCH; + __virtio_unbreak_device(&dev->vdev); r = ioctl(dev->control, VHOST_TEST_RUN, &test); assert(r >= 0); if (!reset_n) { -- 2.36.1
Stefano Garzarella
2022-Jul-04 17:16 UTC
[RFC PATCH 4/6] tools/virtio: move feature negotiation in vdev_info_init()
The feature negotiation are per device, so it' s better to move them earlier in vdev_info_init() since vhost_vq_setup() contains the code to initialize virtqueue. Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- tools/virtio/virtio_test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 765e64895dab..2d8a3e881637 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -69,7 +69,6 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info) { struct vhost_vring_state state = { .index = info->idx }; struct vhost_vring_file file = { .index = info->idx }; - unsigned long long features = dev->vdev.features; struct vhost_vring_addr addr = { .index = info->idx, .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc, @@ -77,8 +76,6 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info) .used_user_addr = (uint64_t)(unsigned long)info->vring.used, }; int r; - r = ioctl(dev->control, VHOST_SET_FEATURES, &features); - assert(r >= 0); state.num = info->vring.num; r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); assert(r >= 0); @@ -149,6 +146,8 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) dev->mem->regions[0].memory_size = dev->buf_size; r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); assert(r >= 0); + r = ioctl(dev->control, VHOST_SET_FEATURES, &features); + assert(r >= 0); } /* TODO: this is pretty bad: we get a cache line bounce -- 2.36.1
Stefano Garzarella
2022-Jul-04 17:17 UTC
[RFC PATCH 5/6] virtio_test: support vhost-vdpa device
The new --vdpa parameter can be used to run virtio_test with the new vdpa_sim_test.ko that implements the device. The main differences with vhost_test are: - control of status register - dma map messages - VHOST_SET_MEM_TABLE not supported by vhost-vdpa - VHOST_TEST_RUN not supported by vhost-vdpa The --reset option is not supported for now when using vhost-vdpa. Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- tools/virtio/virtio_test.c | 127 +++++++++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 18 deletions(-) diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 2d8a3e881637..91f983266d86 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -44,6 +44,8 @@ struct vdev_info { void *buf; size_t buf_size; struct vhost_memory *mem; + bool vdpa; + uint64_t backend_features; }; static const struct vhost_vring_file no_backend = { .fd = -1 }, @@ -64,6 +66,36 @@ void vq_callback(struct virtqueue *vq) { } +static void vdpa_add_status(struct vdev_info *dev, uint8_t status) +{ + uint8_t current_status; + int r; + + r = ioctl(dev->control, VHOST_VDPA_GET_STATUS, ¤t_status); + assert(r >= 0); + current_status |= status; + r = ioctl(dev->control, VHOST_VDPA_SET_STATUS, ¤t_status); + assert(r >= 0); + r = ioctl(dev->control, VHOST_VDPA_GET_STATUS, ¤t_status); + assert(r >= 0); + assert((current_status & status) == status); +} + +static void vdpa_dma_map(struct vdev_info *dev, uint64_t iova, uint64_t size, + uint64_t uaddr, uint8_t perm) +{ + struct vhost_msg_v2 msg = {}; + int r; + + msg.type = VHOST_IOTLB_MSG_V2; + msg.iotlb.iova = iova; + msg.iotlb.size = size; + msg.iotlb.uaddr = uaddr; + msg.iotlb.perm = perm; + msg.iotlb.type = VHOST_IOTLB_UPDATE; + r = write(dev->control, &msg, sizeof(msg)); + assert(r == sizeof(msg)); +} void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info) { @@ -76,6 +108,12 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info) .used_user_addr = (uint64_t)(unsigned long)info->vring.used, }; int r; + if (dev->vdpa) { + vdpa_dma_map(dev, (uint64_t)(unsigned long)info->ring, + vring_size(info->vring.num, 4096), + (uint64_t)(unsigned long)info->ring, + VHOST_ACCESS_RW); + } state.num = info->vring.num; r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); assert(r >= 0); @@ -90,6 +128,11 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info) file.fd = info->call; r = ioctl(dev->control, VHOST_SET_VRING_CALL, &file); assert(r >= 0); + if (dev->vdpa) { + state.num = 1; + r = ioctl(dev->control, VHOST_VDPA_SET_VRING_ENABLE, &state); + assert(r >= 0); + } } static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) @@ -121,33 +164,61 @@ static void vq_info_add(struct vdev_info *dev, int num) dev->nvqs++; } -static void vdev_info_init(struct vdev_info* dev, unsigned long long features) +static void vdev_info_init(struct vdev_info *dev, unsigned long long features, + char *vdpa_dev) { + char *vhost_dev = "/dev/vhost-test"; int r; memset(dev, 0, sizeof *dev); dev->vdev.features = features; + if (vdpa_dev) { + dev->vdpa = true; + vhost_dev = vdpa_dev; + } INIT_LIST_HEAD(&dev->vdev.vqs); spin_lock_init(&dev->vdev.vqs_list_lock); dev->buf_size = 1024; dev->buf = malloc(dev->buf_size); assert(dev->buf); - dev->control = open("/dev/vhost-test", O_RDWR); + dev->control = open(vhost_dev, O_RDWR); assert(dev->control >= 0); r = ioctl(dev->control, VHOST_SET_OWNER, NULL); assert(r >= 0); - dev->mem = malloc(offsetof(struct vhost_memory, regions) + - sizeof dev->mem->regions[0]); - assert(dev->mem); - memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + - sizeof dev->mem->regions[0]); - dev->mem->nregions = 1; - dev->mem->regions[0].guest_phys_addr = (long)dev->buf; - dev->mem->regions[0].userspace_addr = (long)dev->buf; - dev->mem->regions[0].memory_size = dev->buf_size; - r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); - assert(r >= 0); + if (!dev->vdpa) { + dev->mem = malloc(offsetof(struct vhost_memory, regions) + + sizeof(dev->mem->regions[0])); + assert(dev->mem); + memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + + sizeof(dev->mem->regions[0])); + dev->mem->nregions = 1; + dev->mem->regions[0].guest_phys_addr = (long)dev->buf; + dev->mem->regions[0].userspace_addr = (long)dev->buf; + dev->mem->regions[0].memory_size = dev->buf_size; + r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); + assert(r >= 0); + } else { + uint8_t status = 0; + + r = ioctl(dev->control, VHOST_GET_BACKEND_FEATURES, + &dev->backend_features); + assert(r >= 0); + dev->backend_features &= 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2; + assert(dev->backend_features); + r = ioctl(dev->control, VHOST_SET_BACKEND_FEATURES, + &dev->backend_features); + assert(r >= 0); + r = ioctl(dev->control, VHOST_VDPA_SET_STATUS, &status); + assert(r >= 0); + vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | + VIRTIO_CONFIG_S_DRIVER); + vdpa_dma_map(dev, (uint64_t)(unsigned long)dev->buf, + dev->buf_size, (uint64_t)(unsigned long)dev->buf, + VHOST_ACCESS_RW); + } r = ioctl(dev->control, VHOST_SET_FEATURES, &features); assert(r >= 0); + if (dev->vdpa) + vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); } /* TODO: this is pretty bad: we get a cache line bounce @@ -177,8 +248,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, const bool random_batch = batch == RANDOM_BATCH; __virtio_unbreak_device(&dev->vdev); - r = ioctl(dev->control, VHOST_TEST_RUN, &test); - assert(r >= 0); + + if (!dev->vdpa) { + r = ioctl(dev->control, VHOST_TEST_RUN, &test); + assert(r >= 0); + } else { + vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); + } if (!reset_n) { next_reset = INT_MAX; } @@ -268,8 +344,10 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, } } test = 0; - r = ioctl(dev->control, VHOST_TEST_RUN, &test); - assert(r >= 0); + if (!dev->vdpa) { + r = ioctl(dev->control, VHOST_TEST_RUN, &test); + assert(r >= 0); + } fprintf(stderr, "spurious wakeups: 0x%llx started=0x%lx completed=0x%lx\n", spurious, started, completed); @@ -323,6 +401,11 @@ const struct option longopts[] = { .val = 'r', .has_arg = optional_argument, }, + { + .name = "vdpa", + .val = 'V', + .has_arg = required_argument, + }, { } }; @@ -336,6 +419,7 @@ static void help(void) " [--delayed-interrupt]" " [--batch=random/N]" " [--reset=N]" + " [--vdpa=/dev/vhost-vdpa-N]" "\n"); } @@ -347,6 +431,7 @@ int main(int argc, char **argv) long batch = 1, reset = 0; int o; bool delayed = false; + char *vdpa_dev = NULL; for (;;) { o = getopt_long(argc, argv, optstring, longopts, NULL); @@ -389,6 +474,10 @@ int main(int argc, char **argv) assert(reset < (long)INT_MAX + 1); } break; + case 'V': + vdpa_dev = optarg; + features |= 1ULL << VIRTIO_F_ACCESS_PLATFORM; + break; default: assert(0); break; @@ -396,7 +485,9 @@ int main(int argc, char **argv) } done: - vdev_info_init(&dev, features); + //TODO: support reset for vdpa + assert(vdpa_dev && !reset); + vdev_info_init(&dev, features, vdpa_dev); vq_info_add(&dev, 256); run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); return 0; -- 2.36.1
Stefano Garzarella
2022-Jul-04 17:17 UTC
[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 at redhat.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 at redhat.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
? 2022/7/5 01:16, Stefano Garzarella ??:> The first 3 patches fix various problems I have encountered with > virtio_test (they may go without this series, but I included to allow you > to test the series). > > Patch 4 is in preparation of patch 5, moving the feature negotiation when > we initialize the device. > > Patch 5 add the support of vhost-vdpa in virtio_test > > Patch 6 add vdpa_test.ko based on vdpa_sim_test.c, so we can reuse most of > the code coming from the vdpa_sim framework. > > I tested in this way: > > $ modprobe vdpa_sim > $ modprobe vhost-vdpa > > # load the vdpasim_test device > $ insmod vdpa_test.ko > > # create a new vdpasim_test device > $ vdpa dev add mgmtdev vdpasim_test name dev0I wonder what's the benefit of using a dedicated test device other than networking? (already a loopback device anyhow). Thanks> > # run the test using the /dev/vhost-vdpa-0 device > $ ./virtio_test --vdpa /dev/vhost-vdpa-0 > spurious wakeups: 0x0 started=0x100000 completed=0x100000 > > Comments and suggestions are welcome :-) > > Thanks, > Stefano > > Stefano Garzarella (6): > tools/virtio: fix build > vhost_test: add $(srctree) on the included path > virtio_test: call __virtio_unbreak_device > tools/virtio: move feature negotiation in vdev_info_init() > virtio_test: support vhost-vdpa device > vdpasim: add vdpa_sim_test module > > tools/virtio/linux/kernel.h | 2 +- > tools/virtio/linux/virtio.h | 2 + > tools/virtio/linux/vringh.h | 1 + > drivers/vdpa/vdpa_sim/vdpa_sim_test.c | 203 ++++++++++++++++++++++++++ > tools/virtio/vdpa_test/vdpa_test.c | 1 + > tools/virtio/virtio_test.c | 131 ++++++++++++++--- > tools/virtio/Makefile | 32 +++- > tools/virtio/vdpa_test/Makefile | 3 + > tools/virtio/vhost_test/Makefile | 2 +- > 9 files changed, 350 insertions(+), 27 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 >