lkml.org 
[lkml]   [2022]   [Jul]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 5/6] virtio_test: support vhost-vdpa device
    Date
    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@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, &current_status);
    + assert(r >= 0);
    + current_status |= status;
    + r = ioctl(dev->control, VHOST_VDPA_SET_STATUS, &current_status);
    + assert(r >= 0);
    + r = ioctl(dev->control, VHOST_VDPA_GET_STATUS, &current_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
    \
     
     \ /
      Last update: 2022-07-04 19:19    [W:4.296 / U:0.552 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site