Messages in this thread Patch in this message | | | From | Wu Zongyong <> | Subject | [PATCH 5/6] vdpa: add get_vq_num_unchangeable callback in vdpa_config_ops | Date | Wed, 8 Sep 2021 20:20:36 +0800 |
| |
This new callback is used to indicate whether the vring size can be change or not. It is useful when we have a legacy virtio pci device as the vdpa device for there is no way to negotiate the vring num by the specification.
Signed-off-by: Wu Zongyong <wuzongyong@linux.alibaba.com> --- drivers/vhost/vdpa.c | 19 +++++++++++++++++++ drivers/virtio/virtio_vdpa.c | 5 ++++- include/linux/vdpa.h | 4 ++++ include/uapi/linux/vhost.h | 2 ++ 4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 9479f7f79217..2204d27d1e5d 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -350,6 +350,22 @@ static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp) return 0; } +static long vhost_vdpa_get_vring_num_unchangeable(struct vhost_vdpa *v, + u32 __user *argp) +{ + struct vdpa_device *vdpa = v->vdpa; + const struct vdpa_config_ops *ops = vdpa->config; + bool unchangeable = false; + + if (ops->get_vq_num_unchangeable) + unchangeable = ops->get_vq_num_unchangeable(vdpa); + + if (copy_to_user(argp, &unchangeable, sizeof(unchangeable))) + return -EFAULT; + + return 0; +} + static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, void __user *argp) { @@ -487,6 +503,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, case VHOST_VDPA_GET_IOVA_RANGE: r = vhost_vdpa_get_iova_range(v, argp); break; + case VHOST_VDPA_GET_VRING_NUM_UNCHANGEABLE: + r = vhost_vdpa_get_vring_num_unchangeable(v, argp); + break; default: r = vhost_dev_ioctl(&v->vdev, cmd, argp); if (r == -ENOIOCTLCMD) diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c index 72eaef2caeb1..afb47465307a 100644 --- a/drivers/virtio/virtio_vdpa.c +++ b/drivers/virtio/virtio_vdpa.c @@ -146,6 +146,7 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index, struct vdpa_vq_state state = {0}; unsigned long flags; u32 align, num; + bool may_reduce_num = true; int err; if (!name) @@ -171,8 +172,10 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index, /* Create the vring */ align = ops->get_vq_align(vdpa); + if (ops->get_vq_num_unchangeable) + may_reduce_num = !ops->get_vq_num_unchangeable(vdpa); vq = vring_create_virtqueue(index, num, align, vdev, - true, true, ctx, + true, may_reduce_num, ctx, virtio_vdpa_notify, callback, name); if (!vq) { err = -ENOMEM; diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 35648c11e312..f809b7ada00d 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -195,6 +195,9 @@ struct vdpa_iova_range { * @vdev: vdpa device * Returns the iova range supported by * the device. + * @get_vq_num_unchangeable Check if size of virtqueue is unchangeable (optional) + * @vdev: vdpa device + * Returns boolean: unchangeable (true) or not (false) * @set_map: Set device memory mapping (optional) * Needed for device that using device * specific DMA translation (on-chip IOMMU) @@ -262,6 +265,7 @@ struct vdpa_config_ops { const void *buf, unsigned int len); u32 (*get_generation)(struct vdpa_device *vdev); struct vdpa_iova_range (*get_iova_range)(struct vdpa_device *vdev); + bool (*get_vq_num_unchangeable)(struct vdpa_device *vdev); /* DMA ops */ int (*set_map)(struct vdpa_device *vdev, struct vhost_iotlb *iotlb); diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index c998860d7bbc..184f1f7f8498 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h @@ -150,4 +150,6 @@ /* Get the valid iova range */ #define VHOST_VDPA_GET_IOVA_RANGE _IOR(VHOST_VIRTIO, 0x78, \ struct vhost_vdpa_iova_range) +/* Check if the vring size can be change */ +#define VHOST_VDPA_GET_VRING_NUM_UNCHANGEABLE _IOR(VHOST_VIRTIO, 0X79, bool) #endif -- 2.31.1
| |