vdpa: Sync calls set/get config/status with cf_mutex
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 47 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>--- drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++---- drivers/virtio/virtio_vdpa.c | 3 +-- include/linux/vdpa.h | 3 +++ 4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +19
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head);static DEFINE_MUTEX (vdpa_dev_mutex);static DEFINE_IDA (vdpa_index_ida); +u8 vdpa_get_status (struct vdpa_device *vdev) +{ +u8 status; + +mutex_lock (&vdev->cf_mutex); + status = vdev->config->get_status (vdev); +mutex_unlock (&vdev->cf_mutex); +return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ +mutex_lock (&vdev->cf_mutex); + vdev->config->set_status (vdev, status); +mutex_unlock (&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); +static struct genl_family vdpa_nl_family;static int vdpa_dev_probe (struct device *d)drivers/vhost/vdpa.c +0
-0
drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp) · line 147
Quoted 8 lines
drivers/vhost/vdpa.c +1
-2@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)static long vhost_vdpa_get_status (struct vhost_vdpa *v,u8 __user *statusp) {struct vdpa_device *vdpa = v->vdpa; -const struct vdpa_config_ops *ops = vdpa->config;u8 status; - status = ops->get_status (vdpa); + status =vdpa_get_status (vdpa);
Not sure why we need to take cf_mutex here. Appears to me only setters (set_status and reset) need to take the lock in this function.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) · line 166
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1if (copy_to_user (statusp, &status,sizeof (status)))return -EFAULT ;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (copy_from_user (&status, statusp,sizeof (status)))return -EFAULT ; - status_old = ops->get_status (vdpa); + status_old =vdpa_get_status (vdpa);
Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) · line 184
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/* * Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (ret)return ret; }else - ops->set_status (vdpa, status); +vdpa_set_status (vdpa, status);
The reset() call in the if branch above needs to take the cf_mutex, the same way as that for set_status(). The reset() is effectively set_status(vdpa, 0).
Thanks,
-Siwei
Quoted 23 lines
drivers/vhost/vdpa.c +0
-0if ((status &VIRTIO_CONFIG_S_DRIVER_OK ) && !(status_old &VIRTIO_CONFIG_S_DRIVER_OK ))for (i =0 ; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-2@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev)static void virtio_vdpa_set_status (struct virtio_device *vdev,u8 status) {struct vdpa_device *vdpa =vd_get_vdpa (vdev); -const struct vdpa_config_ops *ops = vdpa->config; -return ops->set_status (vdpa, status); +return vdpa_set_status (vdpa, status); }static void virtio_vdpa_reset (struct virtio_device *vdev)include/linux/vdpa.h +0
-0
include/linux/vdpa.h void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, · line 416
Quoted 9 lines
include/linux/vdpa.h +3
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf, unsigned int len);void vdpa_set_config (struct vdpa_device *dev,unsigned int offset,const void *buf,unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); +/** * struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 49 lines · Si-Wei Liu
Quoted 46 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>---
drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++----drivers/virtio/virtio_vdpa.c| 3 +-- include/linux/vdpa.h | 3 +++4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +18
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head); static DEFINE_MUTEX(vdpa_dev_mutex); static DEFINE_IDA(vdpa_index_ida); +u8 vdpa_get_status(struct vdpa_device *vdev) +{ + u8 status; + + mutex_lock(&vdev->cf_mutex); + status = vdev->config->get_status(vdev); + mutex_unlock(&vdev->cf_mutex); + return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ + mutex_lock(&vdev->cf_mutex); + vdev->config->set_status(vdev, status); + mutex_unlock(&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); + static struct genl_family vdpa_nl_family; static int vdpa_dev_probe(struct device *d)drivers/vhost/vdpa.c +0
-0@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)
Quoted 8 lines
drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct · line 148
Quoted 7 lines
drivers/vhost/vdpa.c +1
-1static long vhost_vdpa_get_status(struct vhost_vdpa *v, u8 __user *statusp) { struct vdpa_device *vdpa = v->vdpa; - const struct vdpa_config_ops *ops = vdpa->config; u8 status; - status = ops->get_status(vdpa); + status = vdpa_get_status(vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.
You may be right but it doesn't harm and it is guaranteed to be correct if we protect it with mutex here.
Thanks
Quoted 48 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 167
Quoted 9 lines
drivers/vhost/vdpa.c +1
-0if (copy_to_user(statusp, &status, sizeof(status))) return -EFAULT;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (copy_from_user(&status, statusp, sizeof(status))) return -EFAULT; - status_old = ops->get_status(vdpa); + status_old = vdpa_get_status(vdpa);Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 185
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/** Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (ret) return ret; } else - ops->set_status(vdpa, status); + vdpa_set_status(vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Thanks,
-SiweiQuoted 23 lines
drivers/vhost/vdpa.c +0
-0if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) for (i = 0; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-1@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev) static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) { struct vdpa_device *vdpa = vd_get_vdpa(vdev); - const struct vdpa_config_ops *ops = vdpa->config; - return ops->set_status(vdpa, status); + return vdpa_set_status(vdpa, status); } static void virtio_vdpa_reset(struct virtio_device *vdev)include/linux/vdpa.h +0
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev,unsigned int offset, void *buf, unsigned int len);
Quoted 9 lines
Quoted 8 lines
include/linux/vdpa.h +3
-0void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, const void *buf, unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); + /*** struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 61 lines · Jason Wang
Quoted 49 lines · Si-Wei Liu
Quoted 46 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>---
drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++----drivers/virtio/virtio_vdpa.c| 3 +-- include/linux/vdpa.h | 3 +++4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +18
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head); static DEFINE_MUTEX(vdpa_dev_mutex); static DEFINE_IDA(vdpa_index_ida); +u8 vdpa_get_status(struct vdpa_device *vdev) +{ + u8 status; + + mutex_lock(&vdev->cf_mutex); + status = vdev->config->get_status(vdev); + mutex_unlock(&vdev->cf_mutex); + return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ + mutex_lock(&vdev->cf_mutex); + vdev->config->set_status(vdev, status); + mutex_unlock(&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); + static struct genl_family vdpa_nl_family; static int vdpa_dev_probe(struct device *d)drivers/vhost/vdpa.c +0
-0@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)Quoted 8 lines
drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct · line 148
Quoted 7 lines
drivers/vhost/vdpa.c +1
-1static long vhost_vdpa_get_status(struct vhost_vdpa *v, u8 __user *statusp) { struct vdpa_device *vdpa = v->vdpa; - const struct vdpa_config_ops *ops = vdpa->config; u8 status; - status = ops->get_status(vdpa); + status = vdpa_get_status(vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.
Quoted 1 line
You may be right but it doesn't harm and it is guaranteed to be correct if we protect it with mutex here.
Is it more for future proof? Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held. vhost_vdpa had done its own serialization in vhost_vdpa_unlocked_ioctl() through vhost_dev`mutex.
-Siwei
Quoted 62 lines
Thanks
Quoted 57 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 167
Quoted 9 lines
drivers/vhost/vdpa.c +1
-0if (copy_to_user(statusp, &status, sizeof(status))) return -EFAULT;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (copy_from_user(&status, statusp, sizeof(status))) return -EFAULT; - status_old = ops->get_status(vdpa); + status_old = vdpa_get_status(vdpa);Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 185
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/** Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (ret) return ret; } else - ops->set_status(vdpa, status); + vdpa_set_status(vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Thanks,
-SiweiQuoted 31 lines
drivers/vhost/vdpa.c +0
-0if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) for (i = 0; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-1@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev) static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) { struct vdpa_device *vdpa = vd_get_vdpa(vdev); - const struct vdpa_config_ops *ops = vdpa->config; - return ops->set_status(vdpa, status); + return vdpa_set_status(vdpa, status); } static void virtio_vdpa_reset(struct virtio_device *vdev)include/linux/vdpa.h +3
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev,unsigned int offset, void *buf, unsigned int len); void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, const void *buf, unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); + /*** struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 64 lines · Si-Wei Liu
Quoted 61 lines · Jason Wang
Quoted 57 lines · Si-Wei Liu
Quoted 45 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>---
drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++----drivers/virtio/virtio_vdpa.c| 3 +-- include/linux/vdpa.h | 3 +++4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +18
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head); static DEFINE_MUTEX(vdpa_dev_mutex); static DEFINE_IDA(vdpa_index_ida); +u8 vdpa_get_status(struct vdpa_device *vdev) +{ + u8 status; + + mutex_lock(&vdev->cf_mutex); + status = vdev->config->get_status(vdev); + mutex_unlock(&vdev->cf_mutex); + return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ + mutex_lock(&vdev->cf_mutex); + vdev->config->set_status(vdev, status); + mutex_unlock(&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); + static struct genl_family vdpa_nl_family; static int vdpa_dev_probe(struct device *d)drivers/vhost/vdpa.c +0
-0drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct · line 148
Quoted 8 lines
drivers/vhost/vdpa.c +1
-1@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp) static long vhost_vdpa_get_status(struct vhost_vdpa *v, u8 __user *statusp) { struct vdpa_device *vdpa = v->vdpa; - const struct vdpa_config_ops *ops = vdpa->config; u8 status; - status = ops->get_status(vdpa); + status = vdpa_get_status(vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.
Quoted 2 lines
Quoted 1 line
You may be right but it doesn't harm and it is guaranteed to be correct if we protect it with mutex here.
Is it more for future proof?
I think so.
Quoted 1 line
Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held.
vhost_vdpahad done its own serialization invhost_vdpa_unlocked_ioctl()through vhost_dev`mutex.
Right, but they are done for different levels, one is for vhost_dev antoher is for vdpa_dev.
Thanks
Quoted 66 lines
-Siwei
Quoted 62 lines
Thanks
Quoted 57 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 167
Quoted 9 lines
drivers/vhost/vdpa.c +1
-0if (copy_to_user(statusp, &status, sizeof(status))) return -EFAULT;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (copy_from_user(&status, statusp, sizeof(status))) return -EFAULT; - status_old = ops->get_status(vdpa); + status_old = vdpa_get_status(vdpa);Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 185
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/** Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (ret) return ret; } else - ops->set_status(vdpa, status); + vdpa_set_status(vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Thanks,
-SiweiQuoted 31 lines
drivers/vhost/vdpa.c +0
-0if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) for (i = 0; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-1@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev) static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) { struct vdpa_device *vdpa = vd_get_vdpa(vdev); - const struct vdpa_config_ops *ops = vdpa->config; - return ops->set_status(vdpa, status); + return vdpa_set_status(vdpa, status); } static void virtio_vdpa_reset(struct virtio_device *vdev)include/linux/vdpa.h +3
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev,unsigned int offset, void *buf, unsigned int len); void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, const void *buf, unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); + /*** struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 66 lines · Jason Wang
Quoted 64 lines · Si-Wei Liu
Quoted 61 lines · Jason Wang
Quoted 57 lines · Si-Wei Liu
Quoted 45 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>---
drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++----drivers/virtio/virtio_vdpa.c| 3 +-- include/linux/vdpa.h | 3 +++4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +18
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head); static DEFINE_MUTEX(vdpa_dev_mutex); static DEFINE_IDA(vdpa_index_ida); +u8 vdpa_get_status(struct vdpa_device *vdev) +{ + u8 status; + + mutex_lock(&vdev->cf_mutex); + status = vdev->config->get_status(vdev); + mutex_unlock(&vdev->cf_mutex); + return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ + mutex_lock(&vdev->cf_mutex); + vdev->config->set_status(vdev, status); + mutex_unlock(&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); + static struct genl_family vdpa_nl_family; static int vdpa_dev_probe(struct device *d)drivers/vhost/vdpa.c +0
-0drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct · line 148
Quoted 8 lines
drivers/vhost/vdpa.c +1
-1@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp) static long vhost_vdpa_get_status(struct vhost_vdpa *v, u8 __user *statusp) { struct vdpa_device *vdpa = v->vdpa; - const struct vdpa_config_ops *ops = vdpa->config; u8 status; - status = ops->get_status(vdpa); + status = vdpa_get_status(vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.
Quoted 5 lines
Quoted 2 lines
Quoted 1 line
You may be right but it doesn't harm and it is guaranteed to be correct if we protect it with mutex here.
Is it more for future proof?
I think so.
I guess in this situation it would be better defer to the future patch to add such locking or wrapper, although right now there are just two additional calls taking the lock needlessly when vhost_vdpa_get_status is called. Maybe it's just me but I'm worried some future patch may calls the locked API wrapper thousands of times unintendedly, then the overhead becomes quite obvious.
Quoted 6 lines
Quoted 3 lines
Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held.
vhost_vdpahad done its own serialization invhost_vdpa_unlocked_ioctl()through vhost_dev`mutex.Right, but they are done for different levels, one is for
vhost_devantoher is forvdpa_dev.
The cf_mutex is introduced to serialize the command line configure thread (via netlink) and the upstream driver calls from either the vhost_dev or virtio_dev. I don't see a case, even in future, where the netlink thread needs to update the virtio status on the fly. Can you enlighten me why that is at all possible?
Thanks,
-Siwei
Quoted 71 lines
Thanks
Quoted 66 lines
-Siwei
Quoted 62 lines
Thanks
Quoted 57 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 167
Quoted 9 lines
drivers/vhost/vdpa.c +1
-0if (copy_to_user(statusp, &status, sizeof(status))) return -EFAULT;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (copy_from_user(&status, statusp, sizeof(status))) return -EFAULT; - status_old = ops->get_status(vdpa); + status_old = vdpa_get_status(vdpa);Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 185
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/** Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) if (ret) return ret; } else - ops->set_status(vdpa, status); + vdpa_set_status(vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Thanks,
-SiweiQuoted 31 lines
drivers/vhost/vdpa.c +0
-0if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) for (i = 0; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-1@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev) static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) { struct vdpa_device *vdpa = vd_get_vdpa(vdev); - const struct vdpa_config_ops *ops = vdpa->config; - return ops->set_status(vdpa, status); + return vdpa_set_status(vdpa, status); } static void virtio_vdpa_reset(struct virtio_device *vdev)include/linux/vdpa.h +3
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev,unsigned int offset, void *buf, unsigned int len); void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, const void *buf, unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); + /*** struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 77 lines · Si-Wei Liu
Quoted 73 lines · Jason Wang
Quoted 69 lines · Si-Wei Liu
Quoted 63 lines · Jason Wang
Quoted 51 lines · Si-Wei Liu
Quoted 48 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>--- drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++---- drivers/virtio/virtio_vdpa.c | 3 +-- include/linux/vdpa.h | 3 +++ 4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +18
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head);static DEFINE_MUTEX (vdpa_dev_mutex);static DEFINE_IDA (vdpa_index_ida); +u8 vdpa_get_status(struct vdpa_device *vdev) +{ +u8 status; + +mutex_lock (&vdev->cf_mutex); + status = vdev->config->get_status (vdev); +mutex_unlock (&vdev->cf_mutex); +return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ +mutex_lock (&vdev->cf_mutex); + vdev->config->set_status (vdev, status); +mutex_unlock (&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); +static struct genl_family vdpa_nl_family;static int vdpa_dev_probe (struct device *d)drivers/vhost/vdpa.c +0
-0@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)static long vhost_vdpa_get_status (struct vhost_vdpa *v,u8 __user *statusp)Quoted 8 lines
drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct · line 149
Quoted 6 lines
drivers/vhost/vdpa.c +1
-1{struct vdpa_device *vdpa = v->vdpa; -const struct vdpa_config_ops *ops = vdpa->config;u8 status; - status = ops->get_status (vdpa); + status =vdpa_get_status (vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.Quoted 2 lines
You may be right but it doesn't harm and it is guaranteed to be correct if we protect it with mutex here.
Is it more for future proof?
Quoted 8 lines
Quoted 1 line
I think so.
I guess in this situation it would be better defer to the future patch to add such locking or wrapper, although right now there are just two additional calls taking the lock needlessly when
vhost_vdpa_get_statusis called. Maybe it's just me but I'm worried some future patch may calls the locked API wrapper thousands of times unintendedly, then the overhead becomes quite obvious.
I'm fine to remove this if others agree on this.
Quoted 9 lines
Quoted 9 lines
Quoted 7 lines
Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held.
vhost_vdpahad done its own serialization invhost_vdpa_unlocked_ioctl()through vhost_dev`mutex.
Quoted 7 lines
Quoted 2 lines
Right, but they are done for different levels, one is for
vhost_devantoher is forvdpa_dev.The
cf_mutexis introduced to serialize the command line configure thread (via netlink) and the upstream driver calls from either thevhost_devorvirtio_dev. I don't see a case, even in future, where the netlink thread needs to update the virtio status on the fly. Can you enlighten me why that is at all possible?
After some thought I don't see a case. I can think of NEEDS_RESET but it should come with a config interrupt so we're probably fine without the mutex here.
Thanks
Quoted 80 lines
Thanks,
-SiweiQuoted 76 lines
Thanks
Quoted 71 lines
-Siwei
Quoted 67 lines
Thanks
Quoted 62 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 167
Quoted 9 lines
drivers/vhost/vdpa.c +1
-0if (copy_to_user (statusp, &status,sizeof (status)))return -EFAULT ;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (copy_from_user (&status, statusp,sizeof (status)))return -EFAULT ; - status_old = ops->get_status (vdpa); + status_old =vdpa_get_status (vdpa);Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 185
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/* * Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (ret)return ret; }else - ops->set_status (vdpa, status); +vdpa_set_status (vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Thanks,
-SiweiQuoted 34 lines
drivers/vhost/vdpa.c +0
-0if ((status &VIRTIO_CONFIG_S_DRIVER_OK ) && !(status_old &VIRTIO_CONFIG_S_DRIVER_OK ))for (i = 0; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-1@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev)static void virtio_vdpa_set_status (struct virtio_device *vdev,u8 status) {struct vdpa_device *vdpa =vd_get_vdpa (vdev); -const struct vdpa_config_ops *ops = vdpa->config; - return ops->set_status(vdpa, status); +return vdpa_set_status (vdpa, status); }static void virtio_vdpa_reset (struct virtio_device *vdev)include/linux/vdpa.h +3
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev,unsigned int offset, void *buf, unsigned int len);void vdpa_set_config (struct vdpa_device *dev,unsigned int offset,const void *buf,unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); +/** * struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 5 lines
From: Jason Wang <[email protected]>
Sent: Tuesday, January 11, 2022 10:17 AMQuoted 1 line
Quoted 26 lines
Quoted 6 lines
I guess in this situation it would be better defer to the future patch to add such locking or wrapper, although right now there are just two additional calls taking the lock needlessly when
vhost_vdpa_get_statusis called. Maybe it's just me but I'm worried some future patch may calls the locked API wrapper thousands of times unintendedly, then the overhead becomes quite obvious.I'm fine to remove this if others agree on this.
Quoted 16 lines
Quoted 11 lines
Quoted 7 lines
Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held.
vhost_vdpahad done its own serialization invhost_vdpa_unlocked_ioctl()through vhost_dev`mutex.Right, but they are done for different levels, one is for
vhost_devantoher is forvdpa_dev.The
cf_mutexis introduced to serialize the command line configure thread (via netlink) and the upstream driver calls from either thevhost_devorvirtio_dev. I don't see a case, even in future, where the netlink thread needs to update the virtio status on the fly. Can you enlighten me why that is at all possible?
Sorry for my late response.
Netlink reads the whole space while it is not getting modified by vhost/virtio driver side.
A better to convert cf_mutex to rw_sem that clarifies the code more and still ensure that netlink doesn't read bytes while it is getting modified. Given that config bytes can be updated anytime and not on each field boundary, it is anyway not atomic.
It was added where we wanted to modify the fields post creation, but eventually drop that idea.
So yes, cf_mutex removal is fine too.
Quoted 2 lines
After some thought I don't see a case. I can think of
NEEDS_RESETbut it should come with a config interrupt so we're probably fine without the mutex here.
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 24 lines · Parav Pandit
Quoted 24 lines
From: Jason Wang <[email protected]>
Sent: Tuesday, January 11, 2022 10:17 AMQuoted 6 lines
I guess in this situation it would be better defer to the future patch to add such locking or wrapper, although right now there are just two additional calls taking the lock needlessly when
vhost_vdpa_get_statusis called. Maybe it's just me but I'm worried some future patch may calls the locked API wrapper thousands of times unintendedly, then the overhead becomes quite obvious.I'm fine to remove this if others agree on this.
Quoted 13 lines
Quoted 8 lines
Quoted 5 lines
Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held.
vhost_vdpahad done its own serialization invhost_vdpa_unlocked_ioctl()through vhost_dev`mutex.Right, but they are done for different levels, one is for
vhost_devantoher is forvdpa_dev.The
cf_mutexis introduced to serialize the command line configure thread (via netlink) and the upstream driver calls from either thevhost_devorvirtio_dev. I don't see a case, even in future, where the netlink thread needs to update the virtio status on the fly. Can you enlighten me why that is at all possible?
Quoted 4 lines
Sorry for my late response.
Netlink reads the whole space while it is not getting modified by vhost/virtio driver side.
A better to convertcf_mutextorw_semthat clarifies the code more and still ensure that netlink doesn't read bytes while it is getting modified.
I missed the best timing for asking why it was not a rw_sem in the first place, but I don't mind multi-reader's case too much, so it's not a hurry for me to make the convert.
-Siwei
Quoted 7 lines
Given that config bytes can be updated anytime and not on each field boundary, it is anyway not atomic. It was added where we wanted to modify the fields post creation, but eventually drop that idea.
So yes,
cf_mutexremoval is fine too.Quoted 2 lines
After some thought I don't see a case. I can think of
NEEDS_RESETbut it should come with a config interrupt so we're probably fine without the mutex here.
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 71 lines · Jason Wang
Quoted 70 lines · Si-Wei Liu
Quoted 67 lines · Jason Wang
Quoted 65 lines · Si-Wei Liu
Quoted 60 lines · Jason Wang
Quoted 50 lines · Si-Wei Liu
Quoted 48 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>--- drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++---- drivers/virtio/virtio_vdpa.c | 3 +-- include/linux/vdpa.h | 3 +++ 4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +18
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head);static DEFINE_MUTEX (vdpa_dev_mutex);static DEFINE_IDA (vdpa_index_ida); +u8 vdpa_get_status(struct vdpa_device *vdev) +{ +u8 status; + +mutex_lock (&vdev->cf_mutex); + status = vdev->config->get_status (vdev); +mutex_unlock (&vdev->cf_mutex); +return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ +mutex_lock (&vdev->cf_mutex); + vdev->config->set_status (vdev, status); +mutex_unlock (&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); +static struct genl_family vdpa_nl_family;static int vdpa_dev_probe (struct device *d)drivers/vhost/vdpa.c +0
-0@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)static long vhost_vdpa_get_status (struct vhost_vdpa *v,u8 __user *statusp)Quoted 8 lines
drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct · line 149
Quoted 6 lines
drivers/vhost/vdpa.c +1
-1{struct vdpa_device *vdpa = v->vdpa; -const struct vdpa_config_ops *ops = vdpa->config;u8 status; - status = ops->get_status (vdpa); + status =vdpa_get_status (vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.Quoted 2 lines
You may be right but it doesn't harm and it is guaranteed to be correct if we protect it with mutex here.
Is it more for future proof?
Quoted 8 lines
Quoted 7 lines
Quoted 1 line
I think so.
I guess in this situation it would be better defer to the future patch to add such locking or wrapper, although right now there are just two additional calls taking the lock needlessly when
vhost_vdpa_get_statusis called. Maybe it's just me but I'm worried some future patch may calls the locked API wrapper thousands of times unintendedly, then the overhead becomes quite obvious.I'm fine to remove this if others agree on this.
It looks Parav acked on this. Anyone else?
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 6 lines
Ok, but IMHO it might be better to get some comment here, otherwise it's quite confusing why the lock needs to be held.
vhost_vdpahad done its own serialization invhost_vdpa_unlocked_ioctl()through vhost_dev`mutex.Right, but they are done for different levels, one is for
vhost_devantoher is forvdpa_dev.
Quoted 8 lines
Quoted 5 lines
The
cf_mutexis introduced to serialize the command line configure thread (via netlink) and the upstream driver calls from either thevhost_devorvirtio_dev. I don't see a case, even in future, where the netlink thread needs to update the virtio status on the fly. Can you enlighten me why that is at all possible?After some thought I don't see a case. I can think of
NEEDS_RESETbut it should come with a config interrupt so we're probably fine without the mutex here.
True, it's quite unlikely for netlink to alter the status directly while driver is running. More likely the out of band reset has to reach the guest driver first for it to be aware, which would then initiate the vhost call down to vhost-vdpa through the same path.
-Siwei
Quoted 65 lines
Thanks
Quoted 62 lines
Thanks,
-SiweiQuoted 60 lines
Thanks
Quoted 57 lines
-Siwei
Quoted 55 lines
Thanks
Quoted 52 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 167
Quoted 8 lines
drivers/vhost/vdpa.c +1
-0if (copy_to_user (statusp, &status,sizeof (status)))return -EFAULT ;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (copy_from_user (&status, statusp,sizeof (status)))return -EFAULT ; - status_old = ops->get_status (vdpa); + status_old =vdpa_get_status (vdpa);Ditto.
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct · line 185
Quoted 9 lines
drivers/vhost/vdpa.c +1
-1/* * Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (ret)return ret; }else - ops->set_status (vdpa, status); +vdpa_set_status (vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Thanks,
-SiweiQuoted 26 lines
drivers/vhost/vdpa.c +0
-0if ((status &VIRTIO_CONFIG_S_DRIVER_OK ) && !(status_old &VIRTIO_CONFIG_S_DRIVER_OK ))for (i = 0; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-1@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev)static void virtio_vdpa_set_status (struct virtio_device *vdev,u8 status) {struct vdpa_device *vdpa =vd_get_vdpa (vdev); -const struct vdpa_config_ops *ops = vdpa->config; - return ops->set_status(vdpa, status); +return vdpa_set_status (vdpa, status); }static void virtio_vdpa_reset (struct virtio_device *vdev)include/linux/vdpa.h +0
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev,unsigned int offset, void *buf, unsigned int len);
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
include/linux/vdpa.h +3
-0void vdpa_set_config (struct vdpa_device *dev,unsigned int offset,const void *buf,unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); +/** * struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 58 lines · Eli Cohen
Quoted 48 lines · Si-Wei Liu
Quoted 46 lines · Eli Cohen
Add wrappers to get/set status and protect these operations with
cf_mutexto serialize these operations with respect to get/set config operations.Signed-off-by Eli Cohen <[email protected]>--- drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ drivers/vhost/vdpa.c | 7 +++---- drivers/virtio/virtio_vdpa.c | 3 +-- include/linux/vdpa.h | 3 +++ 4 files changed, 26 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +19
-0@@ -21,6 +21,25 @@ static LIST_HEAD(mdev_head);static DEFINE_MUTEX (vdpa_dev_mutex);static DEFINE_IDA (vdpa_index_ida); +u8 vdpa_get_status (struct vdpa_device *vdev) +{ +u8 status; + +mutex_lock (&vdev->cf_mutex); + status = vdev->config->get_status (vdev); +mutex_unlock (&vdev->cf_mutex); +return status; +} +EXPORT_SYMBOL (vdpa_get_status); + +void vdpa_set_status (struct vdpa_device *vdev,u8 status) +{ +mutex_lock (&vdev->cf_mutex); + vdev->config->set_status (vdev, status); +mutex_unlock (&vdev->cf_mutex); +} +EXPORT_SYMBOL (vdpa_set_status); +static struct genl_family vdpa_nl_family;static int vdpa_dev_probe (struct device *d)drivers/vhost/vdpa.c +0
-0@@ -142,10 +142,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp)static long vhost_vdpa_get_status (struct vhost_vdpa *v,u8 __user *statusp)Quoted 9 lines
drivers/vhost/vdpa.c static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp) · line 146
Quoted 6 lines
drivers/vhost/vdpa.c +1
-2{struct vdpa_device *vdpa = v->vdpa; -const struct vdpa_config_ops *ops = vdpa->config;u8 status; - status = ops->get_status (vdpa); + status =vdpa_get_status (vdpa);Not sure why we need to take
cf_mutexhere. Appears to me only setters (set_statusand reset) need to take the lock in this function.
Quoted 2 lines
What if the implenentation of
get_status()at the upstream driver requires some setup. Takingcf_mutexseems like a good thing to do.
This doesn't like vdpa_get_config() which doesn't need that kind of setup at all currently (though whether the legacy detection in vdpa_get_config is useful or not remains to be a pending question). Even if there's a need in future, we may add it once we get there, right?
It looks to me it's quite unlikely the cf_mutex is needed even in future, since the command line tool would never want to intervene internal virtio status via set_status() from the the netlink thread, while the guest driver is running and in control. It's doubtful this just serves no real purpose for foreseeable future, but just add unwarranted overhead unnecessarily.
Regards,
-Siwei
Quoted 48 lines
Quoted 10 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) · line 165
Quoted 8 lines
drivers/vhost/vdpa.c +1
-1if (copy_to_user (statusp, &status,sizeof (status)))return -EFAULT ;@@ -164,7 +163,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (copy_from_user (&status, statusp,sizeof (status)))return -EFAULT ; - status_old = ops->get_status (vdpa); + status_old =vdpa_get_status (vdpa);Ditto.
Quoted 12 lines
drivers/vhost/vdpa.c static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) · line 184
Quoted 8 lines
drivers/vhost/vdpa.c +1
-1/* * Userspace shouldn't remove status bits unless reset the @@ -182,7 +181,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)if (ret)return ret; }else - ops->set_status (vdpa, status); +vdpa_set_status (vdpa, status);The
reset()call in the if branch above needs to take thecf_mutex, the same way as that forset_status(). Thereset()is effectivelyset_status(vdpa, 0).Right, I missed that. Will send a fix.
Quoted 24 lines
Thanks,
-SiweiQuoted 21 lines
drivers/vhost/vdpa.c +0
-0if ((status &VIRTIO_CONFIG_S_DRIVER_OK ) && !(status_old &VIRTIO_CONFIG_S_DRIVER_OK ))for (i =0 ; i < nvqs; i++)drivers/virtio/virtio_vdpa.c +1
-2@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev)static void virtio_vdpa_set_status (struct virtio_device *vdev,u8 status) {struct vdpa_device *vdpa =vd_get_vdpa (vdev); -const struct vdpa_config_ops *ops = vdpa->config; -return ops->set_status (vdpa, status); +return vdpa_set_status (vdpa, status); }static void virtio_vdpa_reset (struct virtio_device *vdev)include/linux/vdpa.h +0
-0@@ -408,6 +408,9 @@ void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf, unsigned int len);
Quoted 8 lines
Quoted 8 lines
include/linux/vdpa.h void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, · line 416
Quoted 8 lines
include/linux/vdpa.h +3
-0void vdpa_set_config (struct vdpa_device *dev,unsigned int offset,const void *buf,unsigned int length); +u8 vdpa_get_status (struct vdpa_device *vdev); +void vdpa_set_status (struct vdpa_device *vdev,u8 status); +/** * struct vdpa_mgmtdev_ops - vdpa device ops * @dev_add: Add a vdpa device using alloc and register
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v7 05/14] vdpa: Allow to configure max data virtqueues
Quoted 23 lines · Eli Cohen
Add netlink support to configure the max virtqueue pairs for a device. At least one pair is required. The maximum is dictated by the device.
Example:
$ vdpa dev add name vdpa-a mgmtdev auxiliary/mlx5_core.sf.1 max_vqp 4Signed-off-by Eli Cohen <[email protected]>---
v6->v7:
1.Serializeset_featuresand reset usingcf_mutexto ensure consistency with netlink set/getdrivers/vdpa/vdpa.c | 15 +++++++++++++-- drivers/vhost/vdpa.c | 2 +- drivers/virtio/virtio_vdpa.c | 2 +- include/linux/vdpa.h | 19 ++++++++++++++++--- 4 files changed, 31 insertions(+), 7 deletions(-)drivers/vdpa/vdpa.c +0
-0
drivers/vdpa/vdpa.c static void vdpa_get_config_unlocked(struct vdpa_device *vdev, · line 407
Quoted 5 lines
drivers/vdpa/vdpa.c +1
-1@@ -404,7 +404,7 @@ static void vdpa_get_config_unlocked(struct vdpa_device *vdev,* If it does happen we assume a legacy guest. */ if (!vdev->features_valid) -vdpa_set_features (vdev,0 ); +vdpa_set_features (vdev,0 , true);
Can we do it here with an internal unlocked version vdpa_set_features_unlocked() without taking the cf_mutex? Such that all API users for vdpa_set_features() won't have to change the prototype. It looks to me the only place that needs the unlocked API is the vdpa core itself, which doesn't need to expose the internal API to other modules, is my understanding correct?
In addition, it seems more appropriate to move the vdpa_set_features() related changes to a separate patch like patch #3. It's not obvious to me how it's logically connected to the code change for the max_vqp feature here (if there's anything it may be more relevant to patch #8 of this series).
Quoted 71 lines
drivers/vdpa/vdpa.c +12
-1ops->get_config (vdev, offset, buf, len); }@@ -581,7 +581,8 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) }#define VDPA_DEV_NET_ATTRS_MASK ((1 << VDPA_ATTR_DEV_NET_CFG_MACADDR) | \ - (1 << VDPA_ATTR_DEV_NET_CFG_MTU)) + (1 << VDPA_ATTR_DEV_NET_CFG_MTU) | \ + (1 << VDPA_ATTR_DEV_NET_CFG_MAX_VQP))static int vdpa_nl_cmd_dev_add_set_doit (struct sk_buff *skb,struct genl_info *info) {@@ -607,6 +608,16 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *inla_get_u16 (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU ]); config.mask |= (1 <<VDPA_ATTR_DEV_NET_CFG_MTU ); } +if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MAX_VQP ]) { + config.net.max_vq_pairs = +nla_get_u16 (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MAX_VQP ]); +if (!config.net.max_vq_pairs) { +NL_SET_ERR_MSG_MOD (info->extack, +"At least one pair of VQs is required" ); +return -EINVAL ; + } + config.mask |=BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP ); + }/* Skip checking capability if user didn't prefer to configure any * device networking attributes. It is likely that user might have used drivers/vhost/vdpa.c +1
-1@@ -285,7 +285,7 @@ static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)if (copy_from_user (&features, featurep,sizeof (features)))return -EFAULT ; -if (vdpa_set_features (vdpa, features)) +if (vdpa_set_features (vdpa, features, false))return -EINVAL ;return 0 ;drivers/virtio/virtio_vdpa.c +1
-1@@ -317,7 +317,7 @@ static int virtio_vdpa_finalize_features(struct virtio_device *vdev)/* Give virtio_ring a chance to accept features. */ vring_transport_features (vdev); -return vdpa_set_features (vdpa, vdev->features); +return vdpa_set_features (vdpa, vdev->features, false); }static const char *virtio_vdpa_bus_name (struct virtio_device *vdev)include/linux/vdpa.h +1
-0@@ -101,6 +101,7 @@ struct vdpa_dev_set_config {struct {u8 mac[ETH_ALEN ];u16 mtu; +u16 max_vq_pairs; } net;u64 mask; };@@ -391,17 +392,29 @@ static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev)static inline int vdpa_reset (struct vdpa_device *vdev) {
include/linux/vdpa.h static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev) · line 402
Quoted 10 lines
include/linux/vdpa.h +5
-1const struct vdpa_config_ops *ops = vdev->config; +int ret; +mutex_lock (&vdev->cf_mutex); vdev->features_valid = false; -return ops->reset (vdev); + ret = ops->reset (vdev); +mutex_unlock (&vdev->cf_mutex); +return ret; }
Can we move the vdpa_reset() code change here to patch #3? i.e. to be in parallel with set_status() changes.
-Siwei
Quoted 10 lines
include/linux/vdpa.h +5
-1-static inline int vdpa_set_features (struct vdpa_device *vdev,u64 features) +static inline int vdpa_set_features (struct vdpa_device *vdev,u64 features,bool locked) {const struct vdpa_config_ops *ops = vdev->config; +int ret; + +if (!locked) +mutex_lock (&vdev->cf_mutex);
include/linux/vdpa.h static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev) · line 419
Quoted 10 lines
include/linux/vdpa.h +5
-1vdev->features_valid = true; -return ops->set_driver_features (vdev, features); + ret = ops->set_driver_features (vdev, features); +if (!locked) +mutex_unlock (&vdev->cf_mutex); + +return ret; } void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset,
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Si-Wei Liu
Reviewed-byRe: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 68 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +10
-9@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue {struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid (struct mlx5_vdpa_dev *mvdev,u16 idx) {if (unlikely (idx > mvdev->max_idx))@@ -148,8 +143,8 @@ struct mlx5_vdpa_net {struct mlx5_vdpa_dev mvdev;struct mlx5_vdpa_net_resources res;struct virtio_net_config config; -struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS ]; -struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS +1 ]; +struct mlx5_vdpa_virtqueue *vqs; +struct vdpa_callback *event_cbs;/* Serialize vq resources creation and destruction. This is required * since memory map might change and we need to destroy and create @@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) {int i; -for (i =0 ; i <MLX5_MAX_SUPPORTED_VQS ; i++) +for (i =0 ; i < ndev->mvdev.max_vqs; i++)suspend_vq (ndev, &ndev->vqs[i]); }@@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)void *in;int i, j;int err; +int num; - max_rqt =min_t (int,MLX5_MAX_SUPPORTED_VQS /2 , +if (!(ndev->mvdev.actual_features &BIT_ULL (VIRTIO_NET_F_MQ ))) + num =1 ; +else + num =le16_to_cpu (ndev->config.max_virtqueue_pairs); + + max_rqt =min_t (int,roundup_pow_of_two (num),1 <<MLX5_CAP_GEN (ndev->mvdev.mdev, log_max_rqt_size));if (max_rqt <1 )return -EOPNOTSUPP ;
drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1266
Quoted 5 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)MLX5_SET (rqtc, rqtc, rqt_max_size, max_rqt); list =MLX5_ADDR_OF (rqtc, rqtc, rq_num[0 ]);for (i =0 , j =0 ; i < max_rqt; i++, j +=2 ) - list[i] =cpu_to_be32 (ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] =cpu_to_be32 (ndev->vqs[j % (2 * num)].virtq_id);
Good catch. LGTM.
Quoted 66 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +24
-3MLX5_SET (rqtc, rqtc, rqt_actual_size, max_rqt); err =mlx5_vdpa_create_rqt (&ndev->mvdev, in, inlen, &ndev->res.rqtn);@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)clear_vqs_ready (ndev);mlx5_vdpa_destroy_mr (&ndev->mvdev); ndev->mvdev.status =0 ; -memset (ndev->event_cbs,0 ,sizeof (ndev->event_cbs)); +memset (ndev->event_cbs,0 ,sizeof (*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features =0 ; ++mvdev->generation;if (MLX5_CAP_GEN (mvdev->mdev, umem_uid_0)) {@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) }mlx5_vdpa_free_resources (&ndev->mvdev);mutex_destroy (&ndev->reslock); +kfree (ndev->event_cbs); +kfree (ndev->vqs); }static struct vdpa_notification_area mlx5_get_vq_notification (struct vdpa_device *vdev,u16 idx)@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,return -EOPNOTSUPP ; } -/* we save one virtqueue for control virtqueue should we require it */ max_vqs =MLX5_CAP_DEV_VDPA_EMULATION (mdev, max_num_virtio_queues); - max_vqs =min_t (u32, max_vqs,MLX5_MAX_SUPPORTED_VQS ); +if (max_vqs <2 ) { +dev_warn (mdev->device, +"%d virtqueues are supported. At least 2 are required\n" , + max_vqs); +return -EAGAIN ; + } + +if (add_config->mask &BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP )) { +if (add_config->net.max_vq_pairs > max_vqs /2 ) +return -EINVAL ; + max_vqs =min_t (u32, max_vqs,2 * add_config->net.max_vq_pairs); + }else { + max_vqs =2 ; + } ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, name, false);if (IS_ERR (ndev))return PTR_ERR (ndev); + ndev->vqs =kcalloc (max_vqs,sizeof (*ndev->vqs),GFP_KERNEL ); + ndev->event_cbs =kcalloc (max_vqs +1 ,sizeof (*ndev->event_cbs),GFP_KERNEL ); +if (!ndev->vqs || !ndev->event_cbs) { + err = -ENOMEM ; + goto err_alloc; + } ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,mlx5_mpfs_del_mac (pfmdev, config->mac); err_mtu:mutex_destroy (&ndev->reslock); +err_alloc:put_device (&mvdev->vdev.dev);return err; }
drivers/vdpa/mlx5/net/mlx5_vnet.c static int mlx5v_probe(struct auxiliary_device *adev, · line 2698
Quoted 9 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-1@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ) | +BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP ); mgtdev->madev = madev; err =vdpa_mgmtdev_register (&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 75 lines · Si-Wei Liu
Quoted 64 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.
drivers/vdpa/mlx5/net/mlx5_vnet.c| 51 ++++++++++++++++++++++---------1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This is required* since memory map might change and we need to destroy and create @@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); }@@ -1244,8 +1239,14 @@ static int
create_rqt(struct mlx5_vdpa_net *ndev)void *in;
int i, j;
int err;
+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs); +
+max_rqt= min_t(int,roundup_pow_of_two(num),
1 <<MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt< 1)
return-EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>
Apologies to reply to myself. It looks to me we need to set cur_num_vqs to the negotiated num of queues. Otherwise any site referencing cur_num_vqs won't work properly. Further, we need to validate VIRTIO_NET_F_MQ is present in handle_ctrl_mq() before changing the number of queue pairs.
So just disregard my previous R-b for this patch.
Thanks,
-Siwei
Quoted 72 lines
Quoted 72 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation;
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; }- /* we save one virtqueue for control virtqueue should we require it */
max_vqs=MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
+ if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are required\n",
+max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) {
+ if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs= min_t(u32,max_vqs, 2 *add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev =vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, name, false);
if (IS_ERR(ndev))
returnPTR_ERR(ndev);
+ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs=kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }
ndev->mvdev.max_vqs=max_vqs;
mvdev =&ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac);
err_mtu:
mutex_destroy(&ndev->reslock);
+err_alloc:
put_device(&mvdev->vdev.dev);
return err;
}drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device;
Quoted 9 lines
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|
+BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 79 lines · Si-Wei Liu
Quoted 76 lines · Si-Wei Liu
Quoted 65 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.
drivers/vdpa/mlx5/net/mlx5_vnet.c| 51
++++++++++++++++++++++---------1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This is required* since memory map might change and we need to destroy and create @@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); }@@ -1244,8 +1239,14 @@ static int
create_rqt(struct mlx5_vdpa_net *ndev)void *in;
int i, j;
int err;
+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs); +
+max_rqt= min_t(int,roundup_pow_of_two(num),
1 <<MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt< 1)
return-EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 3 lines
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly. Further, we need to validateVIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.
Such validation is not mandated in the spec. And if we want to do that, it needs to be done in a separate patch.
Thanks
Quoted 89 lines
So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 81 lines
Quoted 80 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation;
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; }- /* we save one virtqueue for control virtqueue should we require it */
max_vqs=MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
+ if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are required\n",
+max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) {
+ if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs= min_t(u32,max_vqs, 2 *add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev =vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, name, false);
if (IS_ERR(ndev))
returnPTR_ERR(ndev);
+ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs= kcalloc(max_vqs + 1,sizeof(*ndev->event_cbs),GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }
ndev->mvdev.max_vqs=max_vqs;
mvdev =&ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac);
err_mtu:
mutex_destroy(&ndev->reslock);
+err_alloc:
put_device(&mvdev->vdev.dev);
return err;
}drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|
+BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 82 lines · Jason Wang
Quoted 80 lines · Si-Wei Liu
Quoted 77 lines · Si-Wei Liu
Quoted 65 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.
drivers/vdpa/mlx5/net/mlx5_vnet.c| 51
++++++++++++++++++++++---------1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This is required* since memory map might change and we need to destroy and create @@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); }@@ -1244,8 +1239,14 @@ static int
create_rqt(struct mlx5_vdpa_net *ndev)void *in;
int i, j;
int err;
+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs); +
+max_rqt= min_t(int,roundup_pow_of_two(num),
1 <<MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt< 1)
return-EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net · line 1268
Quoted 7 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 6 lines
Quoted 3 lines
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly. Further, we need to validateVIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.Such validation is not mandated in the spec. And if we want to do that, it needs to be done in a separate patch.
Agreed. The userspace (qemu) has similar validation for software virtio-net although the spec doesn't mandate.
-Siwei
Quoted 95 lines
Thanks
Quoted 90 lines
So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 82 lines
Quoted 81 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt);err =
mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation;
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; }- /* we save one virtqueue for control virtqueue should we require it */
max_vqs=MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
+ if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are
required\n",
+max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) {
+ if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs= min_t(u32,max_vqs, 2 *add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev =vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, name, false);
if (IS_ERR(ndev))
returnPTR_ERR(ndev);
+ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs= kcalloc(max_vqs + 1,sizeof(*ndev->event_cbs),GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }
ndev->mvdev.max_vqs=max_vqs;
mvdev =&ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac);
err_mtu:
mutex_destroy(&ndev->reslock);
+err_alloc:
put_device(&mvdev->vdev.dev);
return err;
}drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2669,7 +2691,8 @@ static int mlx5v_probe(structauxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|
+BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 82 lines · Eli Cohen
Quoted 81 lines · Si-Wei Liu
Quoted 79 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This isrequired
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in;
int i, j;
int err;
+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0+ + max_rqt = min_t(int, roundup_pow_of_two(num), 1 << MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt < 1) return -EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Reviewed-by Si-Wei Liu<[email protected]>
Quoted 8 lines
Quoted 3 lines
Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.
Once VM is rebooted, the cur_num_vqs has to reset to 0 in the reset() op.
Quoted 1 line
create RQT with 1 entry only.
Here cur_num_vqs will be loaded with the newly negotiated value (max_rqt) again.
Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the cur_num_vqs will be consistent with the number of queues newly negotiated (i.e the max_rqt in create_rqt) for modify.
Quoted 3 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting cur_num_vqs in create_rqt (and resetting it in mlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions in change_num_qps() or modify_rqt(). For instances,
create vdpa device with max data VQs = 16
boot VMfeatures_ok set with MQ negotiated
RQT created with 8 entries in create_rqt
ethtool modify num QPs to 2. cur_num_vqs now equals 2.
reboot VMfeatures_ok set with MQ negotiated
RQT created with 8 entries in create_rqt
ethtool modify num QPs to 6.cur_num_vqs was 2 while the actual RQT size is 8 (= 16 / 2)change_num_qps would fail as the wrong increment branch (rather than the decrement) was taken
and this case too, which calls out the need to validate the presence of VIRTIO_NET_F_MQ in handle_ctrl_mq()
create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_ok set with MQ negotiated
RQT created with 8 entries in create_rqt
ethtool modify num QPs to 2. cur_num_vqs now equals 2.
reboot VMfeatures_ok set with no MQ negotiated
RQT created with 8 entries in create_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configure change_num_qps can succeed and no host side check prohibiting a single queue guest to set multi-queue
Thanks,
-Siwei
Quoted 86 lines
Quoted 86 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 76 lines
Quoted 76 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation;
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); + if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are required\n", +max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) { + if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs=min_t(u32, max_vqs, 2 * add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev = vdpa_alloc_device(structmlx5_vdpa_net, mvdev.vdev,mdev->device,&mlx5_vdpa_ops,
name, false);
if (IS_ERR(ndev))
returnPTR_ERR(ndev);
+ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs=kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }
ndev->mvdev.max_vqs=max_vqs;
mvdev =&ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu: mutex_destroy(&ndev->reslock); +err_alloc: put_device(&mvdev->vdev.dev); return err;}
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device;
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|
+BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);
mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 95 lines · Eli Cohen
Quoted 93 lines · Si-Wei Liu
Quoted 90 lines · Eli Cohen
Quoted 79 lines · Si-Wei Liu
Quoted 77 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue {struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net {struct mlx5_vdpa_dev mvdev;struct mlx5_vdpa_net_resources res;struct virtio_net_config config; -struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS ]; -struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS +1 ]; +struct mlx5_vdpa_virtqueue *vqs; +struct vdpa_callback *event_cbs;/* Serialize vq resources creation and destruction. This is required
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) {int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) +for (i =0 ; i < ndev->mvdev.max_vqs; i++)suspend_vq (ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in; int i, j; int err;drivers/vdpa/mlx5/net/mlx5_vnet.c +7
-0+int num; - max_rqt =min_t (int,MLX5_MAX_SUPPORTED_VQS /2 , + if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1; + else + num =le16_to_cpu (ndev->config.max_virtqueue_pairs); + + max_rqt =min_t (int,roundup_pow_of_two (num),1 <<MLX5_CAP_GEN (ndev->mvdev.mdev, log_max_rqt_size));if (max_rqt <1 )return -EOPNOTSUPP ;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)MLX5_SET (rqtc, rqtc, rqt_max_size, max_rqt); list =MLX5_ADDR_OF (rqtc, rqtc, rq_num[0 ]);for (i =0 , j =0 ; i < max_rqt; i++, j +=2 ) - list[i] =cpu_to_be32 (ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] =cpu_to_be32 (ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 5 lines
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.
Quoted 4 lines
Quoted 1 line
Once VM is rebooted, the
cur_num_vqshas to reset to 0 in thereset()op.Why reset to 0? The correct value to set here is
config->max_virtqueue_pairs.
Multiqueue is disabled by default so I think it should be 1 here. This is the behavior of Qemu.
It looks to me we need to clarify this in the spec.
Thanks
Quoted 149 lines
This is what happens when you add the
device. Settingcur_num_vqstoconfig->max_virtqueue_pairswill address your concerns with respect tomodify_rqt. Once you resetcur_num_vqstoconfig->max_virtqueue_pairsyour concerns with respect to changing mumber of QPs should be addressed. We could even leavecreate_rqtuntouched or modify the code to usecur_num_vqs. It should work the same.Quoted 140 lines
Quoted 1 line
create RQT with 1 entry only.
Here
cur_num_vqswill be loaded with the newly negotiated value (max_rqt) again.Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the
cur_num_vqswill be consistent with the number of queues newly negotiated (i.e themax_rqtincreate_rqt) for modify.Quoted 3 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting
cur_num_vqsincreate_rqt(and resetting it inmlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions inchange_num_qps()ormodify_rqt(). For instances,create vdpa device with max data VQs = 16
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6.cur_num_vqswas 2 while the actual RQT size is 8 (= 16 / 2)change_num_qpswould fail as the wrong increment branch (rather than the decrement) was takenand this case too, which calls out the need to validate the presence of
VIRTIO_NET_F_MQinhandle_ctrl_mq()create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with no MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configurechange_num_qpscan succeed and no host side check prohibiting a single queue guest to set multi-queueThanks,
-SiweiQuoted 94 lines
Quoted 94 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 84 lines
Quoted 84 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET (rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)clear_vqs_ready (ndev);mlx5_vdpa_destroy_mr (&ndev->mvdev); ndev->mvdev.status =0 ; -memset (ndev->event_cbs,0 ,sizeof (ndev->event_cbs)); +memset (ndev->event_cbs,0 ,sizeof (*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features =0 ;++mvdev->generation; if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) }mlx5_vdpa_free_resources (&ndev->mvdev);mutex_destroy (&ndev->reslock); +kfree (ndev->event_cbs); +kfree (ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);drivers/vdpa/mlx5/net/mlx5_vnet.c +11
-1- max_vqs =min_t (u32, max_vqs,MLX5_MAX_SUPPORTED_VQS ); +if (max_vqs <2 ) { +dev_warn (mdev->device, +"%d virtqueues are supported. At least 2 are required\n" , + max_vqs); +return -EAGAIN ; + } + +if (add_config->mask &BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP )) { +if (add_config->net.max_vq_pairs > max_vqs /2 ) +return -EINVAL ; + max_vqs = min_t(u32, max_vqs, 2 *
add_config->net.max_vq_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-0+ }else { + max_vqs =2 ; + } ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev,
mdev->device,&mlx5_vdpa_ops,name, false); if (IS_ERR(ndev)) return PTR_ERR(ndev);+
ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs= kcalloc(max_vqs + 1,sizeof(*ndev->event_cbs),GFP_KERNEL);drivers/vdpa/mlx5/net/mlx5_vnet.c +5
-0+if (!ndev->vqs || !ndev->event_cbs) { + err = -ENOMEM ; + goto err_alloc; + } ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu:mutex_destroy (&ndev->reslock); +err_alloc:put_device (&mvdev->vdev.dev);return err;}drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|+ BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP); mgtdev->madev = madev; err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Michael S. Tsirkin
maintainerRe: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 101 lines · Jason Wang
Quoted 95 lines · Eli Cohen
Quoted 93 lines · Si-Wei Liu
Quoted 90 lines · Eli Cohen
Quoted 79 lines · Si-Wei Liu
Quoted 77 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue {struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net {struct mlx5_vdpa_dev mvdev;struct mlx5_vdpa_net_resources res;struct virtio_net_config config; -struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS ]; -struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS +1 ]; +struct mlx5_vdpa_virtqueue *vqs; +struct vdpa_callback *event_cbs;/* Serialize vq resources creation and destruction. This is required
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) {int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) +for (i =0 ; i < ndev->mvdev.max_vqs; i++)suspend_vq (ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in; int i, j; int err;drivers/vdpa/mlx5/net/mlx5_vnet.c +7
-0+int num; - max_rqt =min_t (int,MLX5_MAX_SUPPORTED_VQS /2 , + if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1; + else + num =le16_to_cpu (ndev->config.max_virtqueue_pairs); + + max_rqt =min_t (int,roundup_pow_of_two (num),1 <<MLX5_CAP_GEN (ndev->mvdev.mdev, log_max_rqt_size));if (max_rqt <1 )return -EOPNOTSUPP ;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)MLX5_SET (rqtc, rqtc, rqt_max_size, max_rqt); list =MLX5_ADDR_OF (rqtc, rqtc, rq_num[0 ]);for (i =0 , j =0 ; i < max_rqt; i++, j +=2 ) - list[i] =cpu_to_be32 (ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] =cpu_to_be32 (ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 5 lines
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.Quoted 4 lines
Quoted 1 line
Once VM is rebooted, the
cur_num_vqshas to reset to 0 in thereset()op.Why reset to 0? The correct value to set here is
config->max_virtqueue_pairs.
Quoted 6 lines
Multiqueue is disabled by default so I think it should be 1 here. This is the behavior of Qemu.
It looks to me we need to clarify this in the spec.
Thanks
Not sure what do you want to clarify.
Quoted 141 lines
Quoted 141 lines
This is what happens when you add the
device. Settingcur_num_vqstoconfig->max_virtqueue_pairswill address your concerns with respect tomodify_rqt. Once you resetcur_num_vqstoconfig->max_virtqueue_pairsyour concerns with respect to changing mumber of QPs should be addressed. We could even leavecreate_rqtuntouched or modify the code to usecur_num_vqs. It should work the same.Quoted 133 lines
Quoted 1 line
create RQT with 1 entry only.
Here
cur_num_vqswill be loaded with the newly negotiated value (max_rqt) again.Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the
cur_num_vqswill be consistent with the number of queues newly negotiated (i.e themax_rqtincreate_rqt) for modify.Quoted 3 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting
cur_num_vqsincreate_rqt(and resetting it inmlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions inchange_num_qps()ormodify_rqt(). For instances,create vdpa device with max data VQs = 16
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6.cur_num_vqswas 2 while the actual RQT size is 8 (= 16 / 2)change_num_qpswould fail as the wrong increment branch (rather than the decrement) was takenand this case too, which calls out the need to validate the presence of
VIRTIO_NET_F_MQinhandle_ctrl_mq()create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with no MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configurechange_num_qpscan succeed and no host side check prohibiting a single queue guest to set multi-queueThanks,
-SiweiQuoted 88 lines
Quoted 88 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 78 lines
Quoted 78 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET (rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)clear_vqs_ready (ndev);mlx5_vdpa_destroy_mr (&ndev->mvdev); ndev->mvdev.status =0 ; -memset (ndev->event_cbs,0 ,sizeof (ndev->event_cbs)); +memset (ndev->event_cbs,0 ,sizeof (*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features =0 ;++mvdev->generation; if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) }mlx5_vdpa_free_resources (&ndev->mvdev);mutex_destroy (&ndev->reslock); +kfree (ndev->event_cbs); +kfree (ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);drivers/vdpa/mlx5/net/mlx5_vnet.c +11
-1- max_vqs =min_t (u32, max_vqs,MLX5_MAX_SUPPORTED_VQS ); +if (max_vqs <2 ) { +dev_warn (mdev->device, +"%d virtqueues are supported. At least 2 are required\n" , + max_vqs); +return -EAGAIN ; + } + +if (add_config->mask &BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP )) { +if (add_config->net.max_vq_pairs > max_vqs /2 ) +return -EINVAL ; + max_vqs = min_t(u32, max_vqs, 2 *
add_config->net.max_vq_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-0+ }else { + max_vqs =2 ; + } ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev,
mdev->device,&mlx5_vdpa_ops,name, false); if (IS_ERR(ndev)) return PTR_ERR(ndev);+
ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs= kcalloc(max_vqs + 1,sizeof(*ndev->event_cbs),GFP_KERNEL);drivers/vdpa/mlx5/net/mlx5_vnet.c +5
-0+if (!ndev->vqs || !ndev->event_cbs) { + err = -ENOMEM ; + goto err_alloc; + } ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu:mutex_destroy (&ndev->reslock); +err_alloc:put_device (&mvdev->vdev.dev);return err;}drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-1@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|+ BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP); mgtdev->madev = madev; err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 103 lines · Michael S. Tsirkin
Quoted 101 lines · Jason Wang
Quoted 99 lines · Eli Cohen
Quoted 88 lines · Si-Wei Liu
Quoted 85 lines · Eli Cohen
Quoted 84 lines · Si-Wei Liu
Quoted 77 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue {struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net {struct mlx5_vdpa_dev mvdev;struct mlx5_vdpa_net_resources res;struct virtio_net_config config; -struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS ]; -struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS +1 ]; +struct mlx5_vdpa_virtqueue *vqs; +struct vdpa_callback *event_cbs;/* Serialize vq resources creation and destruction. This is required
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) {int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) +for (i =0 ; i < ndev->mvdev.max_vqs; i++)suspend_vq (ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in; int i, j; int err;drivers/vdpa/mlx5/net/mlx5_vnet.c +7
-0+int num; - max_rqt =min_t (int,MLX5_MAX_SUPPORTED_VQS /2 , + if (!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1; + else + num =le16_to_cpu (ndev->config.max_virtqueue_pairs); + + max_rqt =min_t (int,roundup_pow_of_two (num),1 <<MLX5_CAP_GEN (ndev->mvdev.mdev, log_max_rqt_size));if (max_rqt <1 )return -EOPNOTSUPP ;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)MLX5_SET (rqtc, rqtc, rqt_max_size, max_rqt); list =MLX5_ADDR_OF (rqtc, rqtc, rq_num[0 ]);for (i =0 , j =0 ; i < max_rqt; i++, j +=2 ) - list[i] =cpu_to_be32 (ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] =cpu_to_be32 (ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.Quoted 6 lines
Quoted 5 lines
You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.Once VM is rebooted, the
cur_num_vqshas to reset to 0 in thereset()op.Why reset to 0? The correct value to set here is
config->max_virtqueue_pairs.
Quoted 8 lines
Quoted 6 lines
Multiqueue is disabled by default so I think it should be 1 here. This is the behavior of Qemu.
It looks to me we need to clarify this in the spec.
Thanks
Not sure what do you want to clarify.
Ok, I see this:
Multiqueue is disabled by setting virtqueue_pairs to 1 (this is the default) and waiting for the device to use the command buffer.
So we are fine.
Thanks
Quoted 143 lines
Quoted 143 lines
Quoted 143 lines
This is what happens when you add the
device. Settingcur_num_vqstoconfig->max_virtqueue_pairswill address your concerns with respect tomodify_rqt. Once you resetcur_num_vqstoconfig->max_virtqueue_pairsyour concerns with respect to changing mumber of QPs should be addressed. We could even leavecreate_rqtuntouched or modify the code to usecur_num_vqs. It should work the same.Quoted 133 lines
Quoted 1 line
create RQT with 1 entry only.
Here
cur_num_vqswill be loaded with the newly negotiated value (max_rqt) again.Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the
cur_num_vqswill be consistent with the number of queues newly negotiated (i.e themax_rqtincreate_rqt) for modify.Quoted 3 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting
cur_num_vqsincreate_rqt(and resetting it inmlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions inchange_num_qps()ormodify_rqt(). For instances,create vdpa device with max data VQs = 16
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6.cur_num_vqswas 2 while the actual RQT size is 8 (= 16 / 2)change_num_qpswould fail as the wrong increment branch (rather than the decrement) was takenand this case too, which calls out the need to validate the presence of
VIRTIO_NET_F_MQinhandle_ctrl_mq()create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with no MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configurechange_num_qpscan succeed and no host side check prohibiting a single queue guest to set multi-queueThanks,
-SiweiQuoted 88 lines
Quoted 88 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 78 lines
Quoted 78 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET (rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)clear_vqs_ready (ndev);mlx5_vdpa_destroy_mr (&ndev->mvdev); ndev->mvdev.status =0 ; -memset (ndev->event_cbs,0 ,sizeof (ndev->event_cbs)); +memset (ndev->event_cbs,0 ,sizeof (*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features =0 ;++mvdev->generation; if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) }mlx5_vdpa_free_resources (&ndev->mvdev);mutex_destroy (&ndev->reslock); +kfree (ndev->event_cbs); +kfree (ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);drivers/vdpa/mlx5/net/mlx5_vnet.c +11
-1- max_vqs =min_t (u32, max_vqs,MLX5_MAX_SUPPORTED_VQS ); +if (max_vqs <2 ) { +dev_warn (mdev->device, +"%d virtqueues are supported. At least 2 are required\n" , + max_vqs); +return -EAGAIN ; + } + +if (add_config->mask &BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP )) { +if (add_config->net.max_vq_pairs > max_vqs /2 ) +return -EINVAL ; + max_vqs = min_t(u32, max_vqs, 2 *
add_config->net.max_vq_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-0+ }else { + max_vqs =2 ; + } ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev,
mdev->device,&mlx5_vdpa_ops,name, false); if (IS_ERR(ndev)) return PTR_ERR(ndev);+
ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs= kcalloc(max_vqs + 1,sizeof(*ndev->event_cbs),GFP_KERNEL);drivers/vdpa/mlx5/net/mlx5_vnet.c +5
-0+if (!ndev->vqs || !ndev->event_cbs) { + err = -ENOMEM ; + goto err_alloc; + } ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu:mutex_destroy (&ndev->reslock); +err_alloc:put_device (&mvdev->vdev.dev);return err;}drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-1@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|+ BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP); mgtdev->madev = madev; err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
In reply to a message not in the archiveQuoted 86 lines · Eli Cohen
Quoted 85 lines · Si-Wei Liu
Quoted 83 lines · Eli Cohen
Quoted 82 lines · Si-Wei Liu
Quoted 76 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This isrequired
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in;
int i, j;
int err;
+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0+ + max_rqt = min_t(int, roundup_pow_of_two(num), 1 << MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt < 1) return -EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.
Quoted 8 lines
Quoted 6 lines
Quoted 5 lines
You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.Once VM is rebooted, the
cur_num_vqshas to reset to 0 in thereset()op.Why reset to 0? The correct value to set here is
config->max_virtqueue_pairs.
I am not sure I get you, perhaps post a patch to show what you want to do? If you intend to set to 2 (non-MQ) or 2 * max_virtqueue_pairs (MQ) later in create_rqt(), maybe it's not quite relevant whether or not to reset. But in the habit of keeping things consistent I'd prefer reset to a value to reflect the fact that this field won't have a valid value until features are negotiated. Whenever there's a need in future, this field can be easily exposed to userspace.
Quoted 2 lines
This is what happens when you add the
device.
This is not relevant, and doesn't matter. Essentially that line of code to set cur_num_vqs in vdpa_add can be removed. The value of cur_num_vqs won't be effective before the MQ feature is negotiated, i.e. you don't get a sensible cur_num_vqs value before the size of RQT is derived from the MQ feature and the table gets created.
Quoted 4 lines
Setting
cur_num_vqstoconfig->max_virtqueue_pairswill address
your concerns with respect tomodify_rqt. Once you resetcur_num_vqstoconfig->max_virtqueue_pairsyour concerns with respect to changing mumber of QPs should be addressed.
No, it won't. If you look at the caller of change_num_qps(), in handle_ctrl_mq() there's following code:
if (ndev->cur_num_vqs == 2 * newqps) { status = VIRTIO_NET_OK; break;
}
So if you set cur_num_vqs to max_virtqueue_pairs while MQ is not negotiated, it will result in a very weird success for a non-MQ supporting driver to be able to change the number of queues without changing anything effectively. You may argue that we can fail the non-MQ case early before coming to this code. But this is another patch, and would make code more obscure, not less. Intuitively people won't realize your cur_num_vqs doesn't apply to non-MQ just by follow the name.
Regards,
-Siwei
Quoted 133 lines
We could even leave
create_rqt
untouched or modify the code to usecur_num_vqs. It should work the same.Quoted 129 lines
Quoted 1 line
create RQT with 1 entry only.
Here
cur_num_vqswill be loaded with the newly negotiated value (max_rqt) again.Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the
cur_num_vqswill be consistent with the number of queues newly negotiated (i.e themax_rqtincreate_rqt) for modify.Quoted 2 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting
cur_num_vqsincreate_rqt(and resetting it inmlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions inchange_num_qps()ormodify_rqt(). For instances,create vdpa device with max data VQs = 16
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6.cur_num_vqswas 2 while the actual RQT size is 8 (= 16 / 2)change_num_qpswould fail as the wrong increment branch (rather than the decrement) was takenand this case too, which calls out the need to validate the presence of
VIRTIO_NET_F_MQinhandle_ctrl_mq()create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with no MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configurechange_num_qpscan succeed and no host side check prohibiting a single queue guest to set multi-queueThanks,
-SiweiQuoted 85 lines
Quoted 85 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 76 lines
Quoted 76 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation; if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); + if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are required\n", +max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) { + if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs=min_t(u32, max_vqs, 2 * add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev = vdpa_alloc_device(structmlx5_vdpa_net, mvdev.vdev,mdev->device,&mlx5_vdpa_ops,
name, false);
if (IS_ERR(ndev))
returnPTR_ERR(ndev);
+ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs=kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }
ndev->mvdev.max_vqs=max_vqs;
mvdev =&ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu: mutex_destroy(&ndev->reslock); +err_alloc: put_device(&mvdev->vdev.dev); return err;}drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device;
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|
+BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);
mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Michael S. Tsirkin
maintainerRe: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 144 lines · Eli Cohen
Quoted 134 lines · Si-Wei Liu
Quoted 86 lines · Eli Cohen
Quoted 85 lines · Si-Wei Liu
Quoted 83 lines · Eli Cohen
Quoted 82 lines · Si-Wei Liu
Quoted 76 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This isrequired
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in;
int i, j;
int err;
+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0+ + max_rqt = min_t(int, roundup_pow_of_two(num), 1 << MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt < 1) return -EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.Quoted 8 lines
Quoted 6 lines
Quoted 5 lines
You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.Once VM is rebooted, the
cur_num_vqshas to reset to 0 in thereset()op.Why reset to 0? The correct value to set here is
config->max_virtqueue_pairs.I am not sure I get you, perhaps post a patch to show what you want to do? If you intend to set to 2 (non-MQ) or 2 *
max_virtqueue_pairs(MQ) later increate_rqt(), maybe it's not quite relevant whether or not to reset. But in the habit of keeping things consistent I'd prefer reset to a value to reflect the fact that this field won't have a valid value until features are negotiated. Whenever there's a need in future, this field can be easily exposed to userspace.Quoted 2 lines
This is what happens when you add the
device.This is not relevant, and doesn't matter. Essentially that line of code to set
cur_num_vqsinvdpa_addcan be removed. The value ofcur_num_vqswon't be effective before the MQ feature is negotiated, i.e. you don't get a sensiblecur_num_vqsvalue before the size of RQT is derived from the MQ feature and the table gets created.Quoted 4 lines
Setting
cur_num_vqstoconfig->max_virtqueue_pairswill address
your concerns with respect tomodify_rqt. Once you resetcur_num_vqstoconfig->max_virtqueue_pairsyour concerns with respect to changing mumber of QPs should be addressed.No, it won't. If you look at the caller of
change_num_qps(), inhandle_ctrl_mq()there's following code:if (
ndev->cur_num_vqs== 2 * newqps) { status =VIRTIO_NET_OK; break;
}So if you set
cur_num_vqstomax_virtqueue_pairswhile MQ is not negotiated, it will result in a very weird success for a non-MQ supporting driver to be able to change the number of queues without changing anything effectively. You may argue that we can fail the non-MQ case early before coming to this code. But this is another patch, and would make code more obscure, not less. Intuitively people won't realize yourcur_num_vqsdoesn't apply to non-MQ just by follow the name.Quoted 3 lines
Regards,
-SiweiSi-Wei:
So your point is that you want to seecur_num_vqs0 feature negotiated and other 2 for non MQ, and whatever configured through ethtool otherwise.
Quoted 8 lines
I can send a patch to address this concern of yours.
Quesiton is how we want to proceed here. I do want this series to get into 5.16. Should I send a new series or fixes on top of this? Also, it would be helpful if you could list all the changes you think should be made.
Michael: what do you think?
Fixes on top is best, including the Fixes tag.
Merge window is open, so
what's there right now should be pretty close to what goes into rc1. If possible please send a patchset with all fixes so it's possible to evaluate whether we are there or it has to be pushed out to 5.17 (hope not). If there are cleanups we can push out to rc2 pls make that clear too.
Quoted 135 lines
Quoted 135 lines
Quoted 135 lines
We could even leave
create_rqt
untouched or modify the code to usecur_num_vqs. It should work the same.Quoted 130 lines
Quoted 1 line
create RQT with 1 entry only.
Here
cur_num_vqswill be loaded with the newly negotiated value (max_rqt) again.Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the
cur_num_vqswill be consistent with the number of queues newly negotiated (i.e themax_rqtincreate_rqt) for modify.Quoted 2 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting
cur_num_vqsincreate_rqt(and resetting it inmlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions inchange_num_qps()ormodify_rqt(). For instances,create vdpa device with max data VQs = 16
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6.cur_num_vqswas 2 while the actual RQT size is 8 (= 16 / 2)change_num_qpswould fail as the wrong increment branch (rather than the decrement) was takenand this case too, which calls out the need to validate the presence of
VIRTIO_NET_F_MQinhandle_ctrl_mq()create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with no MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configurechange_num_qpscan succeed and no host side check prohibiting a single queue guest to set multi-queueThanks,
-SiweiQuoted 86 lines
Quoted 86 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 77 lines
Quoted 77 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation; if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); + if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are required\n", +max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) { + if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs=min_t(u32, max_vqs, 2 * add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev = vdpa_alloc_device(structmlx5_vdpa_net, mvdev.vdev,mdev->device,&mlx5_vdpa_ops,
name, false);
if (IS_ERR(ndev))
returnPTR_ERR(ndev);
+ndev->vqs=kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);
+ndev->event_cbs=kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }
ndev->mvdev.max_vqs=max_vqs;
mvdev =&ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu: mutex_destroy(&ndev->reslock); +err_alloc: put_device(&mvdev->vdev.dev); return err;}drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table;
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1- mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|
+BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);
mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
In reply to a message not in the archiveQuoted 136 lines · Eli Cohen
Quoted 132 lines · Si-Wei Liu
Quoted 85 lines · Eli Cohen
Quoted 84 lines · Si-Wei Liu
Quoted 83 lines · Eli Cohen
Quoted 82 lines · Si-Wei Liu
Quoted 76 lines · Si-Wei Liu
Quoted 67 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-6@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue { struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) { if (unlikely(idx > mvdev->max_idx)) @@ -148,8 +143,8 @@ struct mlx5_vdpa_net { struct mlx5_vdpa_dev mvdev; struct mlx5_vdpa_net_resources res; struct virtio_net_config config; - struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS]; - struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS + 1]; + struct mlx5_vdpa_virtqueue *vqs; + struct vdpa_callback *event_cbs; /* Serialize vq resources creation and destruction. This isrequired
* since memory map might change and we need to destroy and createdrivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) { int i; - for (i = 0; i < MLX5_MAX_SUPPORTED_VQS; i++) + for (i = 0; i < ndev->mvdev.max_vqs; i++) suspend_vq(ndev, &ndev->vqs[i]); } @@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net*ndev)
void *in; int i, j; int err;+ int num;
-max_rqt= min_t(int,MLX5_MAX_SUPPORTED_VQS/ 2,
+ if (!(ndev->mvdev.actual_features &BIT_ULL(VIRTIO_NET_F_MQ))) + num = 1;
+ else
+ num =le16_to_cpu(ndev->config.max_virtqueue_pairs);drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0+ + max_rqt = min_t(int, roundup_pow_of_two(num), 1 << MLX5_CAP_GEN(ndev->mvdev.mdev, log_max_rqt_size)); if (max_rqt < 1) return -EOPNOTSUPP;drivers/vdpa/mlx5/net/mlx5_vnet.c static int create_rqt(struct mlx5_vdpa_net *ndev) · line 1267
Quoted 6 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) MLX5_SET(rqtc, rqtc, rqt_max_size, max_rqt); list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); for (i = 0, j = 0; i < max_rqt; i++, j += 2) - list[i] = cpu_to_be32(ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] = cpu_to_be32(ndev->vqs[j % (2 * num)].virtq_id);Good catch. LGTM.
Quoted 2 lines
Reviewed-by Si-Wei Liu<[email protected]>Apologies to reply to myself. It looks to me we need to set
cur_num_vqsto the negotiated num of queues. Otherwise any site referencingcur_num_vqswon't work properly.Quoted 8 lines
Quoted 6 lines
Quoted 5 lines
You can't really use
cur_num_vqs. Consider this scenario:
create vdpa device with max VQs = 16 (RQT size created with 8 entries) boot VM
ethtool modify num QPs to 2.cur_num_vqsnow equals 2. reboot VM.Once VM is rebooted, the
cur_num_vqshas to reset to 0 in thereset()op.Why reset to 0? The correct value to set here is
config->max_virtqueue_pairs.I am not sure I get you, perhaps post a patch to show what you want to do? If you intend to set to 2 (non-MQ) or 2 *
max_virtqueue_pairs(MQ) later increate_rqt(), maybe it's not quite relevant whether or not to reset. But in the habit of keeping things consistent I'd prefer reset to a value to reflect the fact that this field won't have a valid value until features are negotiated. Whenever there's a need in future, this field can be easily exposed to userspace.Quoted 2 lines
This is what happens when you add the
device.This is not relevant, and doesn't matter. Essentially that line of code to set
cur_num_vqsinvdpa_addcan be removed. The value ofcur_num_vqswon't be effective before the MQ feature is negotiated, i.e. you don't get a sensiblecur_num_vqsvalue before the size of RQT is derived from the MQ feature and the table gets created.Quoted 4 lines
Setting cur_num_vqs to config->max_virtqueue_pairs will addressyour concerns with respect to
modify_rqt. Once you resetcur_num_vqstoconfig->max_virtqueue_pairsyour concerns with respect to changing mumber of QPs should be addressed.No, it won't. If you look at the caller of
change_num_qps(), inhandle_ctrl_mq()there's following code:if (
ndev->cur_num_vqs== 2 * newqps) { status =VIRTIO_NET_OK; break;
}So if you set
cur_num_vqstomax_virtqueue_pairswhile MQ is not negotiated, it will result in a very weird success for a non-MQ supporting driver to be able to change the number of queues without changing anything effectively. You may argue that we can fail the non-MQ case early before coming to this code. But this is another patch, and would make code more obscure, not less. Intuitively people won't realize yourcur_num_vqsdoesn't apply to non-MQ just by follow the name.Quoted 3 lines
Regards,
-Siwei
Quoted 6 lines
Si-Wei:
So your point is that you want to seecur_num_vqs0 feature negotiated and other 2 for non MQ, and whatever configured through ethtool otherwise.I can send a patch to address this concern of yours.
Thanks, Eli!
Quoted 3 lines
Quesiton is how we want to proceed here. I do want this series to get into 5.16. Should I send a new series or fixes on top of this?
Yep, fixes on top should be fine. I already gave R-b on your fixes. This should pretty much close the review loop. Thanks for your hard work on this!
Quoted 3 lines
Also, it
would be helpful if you could list all the changes you think should be made.
There are a couple cosmetic changes, but doesn't matter anyway. I think your latest fixes address the major comments, and I can post patches myself to address the rest.
Thanks!
-Siwei
Quoted 136 lines
Michael: what do you think?
Quoted 133 lines
Quoted 133 lines
We could even leave
create_rqt
untouched or modify the code to usecur_num_vqs. It should work the same.Quoted 129 lines
Quoted 1 line
create RQT with 1 entry only.
Here
cur_num_vqswill be loaded with the newly negotiated value (max_rqt) again.Quoted 2 lines
ethtool modify num QPs to 4. modify RQT will fail since it was created with max QPs equals 1.
It won't fail as the
cur_num_vqswill be consistent with the number of queues newly negotiated (i.e themax_rqtincreate_rqt) for modify.Quoted 2 lines
I think it is ok to create the RQT always with the value configured when the device was created.
The problem of not setting
cur_num_vqsincreate_rqt(and resetting it inmlx5_vdpa_reset) is that, once the VM is rebooted or the device is reset, the value doesn't go with the actual number of rqt entries hence would break various assumptions inchange_num_qps()ormodify_rqt(). For instances,create vdpa device with max data VQs = 16
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6.cur_num_vqswas 2 while the actual RQT size is 8 (= 16 / 2)change_num_qpswould fail as the wrong increment branch (rather than the decrement) was takenand this case too, which calls out the need to validate the presence of
VIRTIO_NET_F_MQinhandle_ctrl_mq()create vdpa device with max data VQs = 16 (RQT size created with 8 entries)
boot VMfeatures_okset with MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 2.cur_num_vqsnow equals 2.
reboot VMfeatures_okset with no MQ negotiated
RQT created with 8 entries increate_rqt
ethtool modify num QPs to 6. suppose guest runs a custom kernel without checking the #channels to configurechange_num_qpscan succeed and no host side check prohibiting a single queue guest to set multi-queueThanks,
-SiweiQuoted 85 lines
Quoted 85 lines
Further, we need to validate
VIRTIO_NET_F_MQis present inhandle_ctrl_mq()before changing the number of queue pairs.So just disregard my previous R-b for this patch.
Thanks,
-SiweiQuoted 76 lines
Quoted 76 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0MLX5_SET(rqtc, rqtc, rqt_actual_size, max_rqt); err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen,
&ndev->res.rqtn);drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); + memset(ndev->event_cbs, 0, sizeof(*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features = 0;++mvdev->generation; if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-0@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) } mlx5_vdpa_free_resources(&ndev->mvdev); mutex_destroy(&ndev->reslock); + kfree(ndev->event_cbs); + kfree(ndev->vqs); } static struct vdpa_notification_area
mlx5_get_vq_notification(struct vdpa_device *vdev, u16 idx)drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, return -EOPNOTSUPP; } - /* we save one virtqueue for control virtqueue should werequire it */
max_vqs= MLX5_CAP_DEV_VDPA_EMULATION(mdev,max_num_virtio_queues);
-max_vqs=min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS); + if (max_vqs< 2) {
+ dev_warn(mdev->device,
+ "%d virtqueues are supported. At least 2 are required\n", +max_vqs);
+ return-EAGAIN;
+ }
+
+ if (add_config->mask&BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) { + if (add_config->net.max_vq_pairs>max_vqs/ 2)
+ return-EINVAL;
+max_vqs=min_t(u32, max_vqs, 2 * add_config->net.max_vq_pairs);
+ } else {
+max_vqs= 2;
+ }
ndev = vdpa_alloc_device(structmlx5_vdpa_net, mvdev.vdev,mdev->device,&mlx5_vdpa_ops,name, false); if (IS_ERR(ndev)) return PTR_ERR(ndev); + ndev->vqs = kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL);+
ndev->event_cbs= kcalloc(max_vqs + 1,sizeof(*ndev->event_cbs),GFP_KERNEL);
+ if (!ndev->vqs || !ndev->event_cbs) {
+ err =-ENOMEM;
+ gotoerr_alloc;
+ }ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_mpfs_del_mac(pfmdev, config->mac); err_mtu: mutex_destroy(&ndev->reslock); +err_alloc: put_device(&mvdev->vdev.dev); return err;}drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device;
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-1mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|+ BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP); mgtdev->madev = madev; err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
In reply to Si-Wei LiuApologies if this reply is somewhat mangled. This patch did not appear to make it to the mailing list so I had to use another reply that did to base it on.
Quoted 108 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +28
-13@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue {struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid (struct mlx5_vdpa_dev *mvdev,u16 idx) {if (unlikely (idx > mvdev->max_idx))@@ -148,8 +143,8 @@ struct mlx5_vdpa_net {struct mlx5_vdpa_dev mvdev;struct mlx5_vdpa_net_resources res;struct virtio_net_config config; -struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS ]; -struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS +1 ]; +struct mlx5_vdpa_virtqueue *vqs; +struct vdpa_callback *event_cbs;/* Serialize vq resources creation and destruction. This is required * since memory map might change and we need to destroy and create @@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) {int i; -for (i =0 ; i <MLX5_MAX_SUPPORTED_VQS ; i++) +for (i =0 ; i < ndev->mvdev.max_vqs; i++)suspend_vq (ndev, &ndev->vqs[i]); }@@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)void *in;int i, j;int err; +int num; - max_rqt =min_t (int,MLX5_MAX_SUPPORTED_VQS /2 , +if (!(ndev->mvdev.actual_features &BIT_ULL (VIRTIO_NET_F_MQ ))) + num =1 ; +else + num =le16_to_cpu (ndev->config.max_virtqueue_pairs); + + max_rqt =min_t (int,roundup_pow_of_two (num),1 <<MLX5_CAP_GEN (ndev->mvdev.mdev, log_max_rqt_size));if (max_rqt <1 )return -EOPNOTSUPP ;@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)MLX5_SET (rqtc, rqtc, rqt_max_size, max_rqt); list =MLX5_ADDR_OF (rqtc, rqtc, rq_num[0 ]);for (i =0 , j =0 ; i < max_rqt; i++, j +=2 ) - list[i] =cpu_to_be32 (ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] =cpu_to_be32 (ndev->vqs[j % (2 * num)].virtq_id);MLX5_SET (rqtc, rqtc, rqt_actual_size, max_rqt); err =mlx5_vdpa_create_rqt (&ndev->mvdev, in, inlen, &ndev->res.rqtn);@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)clear_vqs_ready (ndev);mlx5_vdpa_destroy_mr (&ndev->mvdev); ndev->mvdev.status =0 ; -memset (ndev->event_cbs,0 ,sizeof (ndev->event_cbs)); +memset (ndev->event_cbs,0 ,sizeof (*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features =0 ; ++mvdev->generation;if (MLX5_CAP_GEN (mvdev->mdev, umem_uid_0)) {@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) }mlx5_vdpa_free_resources (&ndev->mvdev);mutex_destroy (&ndev->reslock); +kfree (ndev->event_cbs); +kfree (ndev->vqs); }static struct vdpa_notification_area mlx5_get_vq_notification (struct vdpa_device *vdev,u16 idx)@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,return -EOPNOTSUPP ; } -/* we save one virtqueue for control virtqueue should we require it */ max_vqs =MLX5_CAP_DEV_VDPA_EMULATION (mdev, max_num_virtio_queues); - max_vqs =min_t (u32, max_vqs,MLX5_MAX_SUPPORTED_VQS ); +if (max_vqs <2 ) { +dev_warn (mdev->device, +"%d virtqueues are supported. At least 2 are required\n" , + max_vqs); +return -EAGAIN ; + } + +if (add_config->mask &BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP )) { +if (add_config->net.max_vq_pairs > max_vqs /2 ) +return -EINVAL ; + max_vqs =min_t (u32, max_vqs,2 * add_config->net.max_vq_pairs); + }else { + max_vqs =2 ; + }
drivers/vdpa/mlx5/net/mlx5_vnet.c static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, · line 2567
Quoted 10 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +6
-0ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, name, false);if (IS_ERR (ndev))return PTR_ERR (ndev); + ndev->vqs =kcalloc (max_vqs,sizeof (*ndev->vqs),GFP_KERNEL ); + ndev->event_cbs =kcalloc (max_vqs +1 ,sizeof (*ndev->event_cbs),GFP_KERNEL ); +if (!ndev->vqs || !ndev->event_cbs) { + err = -ENOMEM ; + goto err_alloc; + }
Clang warns:
drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:6: error: variable 'mvdev' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
if (!ndev->vqs || !ndev->event_cbs) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/vdpa/mlx5/net/mlx5_vnet.c:2660:14: note: uninitialized use occurs here
put_device(&mvdev->vdev.dev);
^~~~~
drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:2: note: remove the 'if' if its condition is always false
if (!ndev->vqs || !ndev->event_cbs) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:6: error: variable 'mvdev' is used uninitialized whenever '||' condition is true [-Werror,-Wsometimes-uninitialized]
if (!ndev->vqs || !ndev->event_cbs) {
^~~~~~~~~~
drivers/vdpa/mlx5/net/mlx5_vnet.c:2660:14: note: uninitialized use occurs here
put_device(&mvdev->vdev.dev);
^~~~~
drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:6: note: remove the '||' if its condition is always false
if (!ndev->vqs || !ndev->event_cbs) {
^~~~~~~~~~~~~
drivers/vdpa/mlx5/net/mlx5_vnet.c:2534:29: note: initialize the variable 'mvdev' to silence this warning
struct mlx5_vdpa_dev *mvdev;
^
= NULL2 errors generated.
I was going to send a patch just moving "err_alloc" right above "return err;" but I don't think that is a proper fix. I think this patch is going to result in memory leaks on the err_mpfs and err_mtu paths, as ndev->vqs and ndev->event_cbs will have been allocated but they are only cleaned up in mlx5_vdpa_free_resources(). Additionally, I don't think the results of these allocations should be checked together, because one could succeed and the other could fail, meaning one needs to be cleaned up while the other doesn't.
Cheers,
Nathan
Quoted 20 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-1ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,mlx5_mpfs_del_mac (pfmdev, config->mac); err_mtu:mutex_destroy (&ndev->reslock); +err_alloc:put_device (&mvdev->vdev.dev);return err; }@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ) | +BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP ); mgtdev->madev = madev; err =vdpa_mgmtdev_register (&mgtdev->mgtdev);
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
It's unfortunate. Don't know why this series got pulled into linux-next prematurely. The code review is still on going and there were outstanding comments that hadn't been addressed yet.
Quoted 172 lines · Nathan Chancellor
Apologies if this reply is somewhat mangled. This patch did not appear to make it to the mailing list so I had to use another reply that did to base it on.
Quoted 108 lines · Eli Cohen
Check whether the max number of data virtqueue pairs was provided when a adding a new device and verify the new value does not exceed device capabilities.
In addition, change the arrays holding virtqueue and callback contexts to be dynamically allocated.
Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Evaluate RQT table size based on config.max_virtqueue_pairs.drivers/vdpa/mlx5/net/mlx5_vnet.c | 51 ++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +28
-13@@ -131,11 +131,6 @@ struct mlx5_vdpa_virtqueue {struct mlx5_vq_restore_info ri; }; -/* We will remove this limitation once mlx5_vdpa_alloc_resources() -* provides for driver space allocation -*/ -#define MLX5_MAX_SUPPORTED_VQS 16 -static bool is_index_valid (struct mlx5_vdpa_dev *mvdev,u16 idx) {if (unlikely (idx > mvdev->max_idx))@@ -148,8 +143,8 @@ struct mlx5_vdpa_net {struct mlx5_vdpa_dev mvdev;struct mlx5_vdpa_net_resources res;struct virtio_net_config config; -struct mlx5_vdpa_virtqueue vqs[MLX5_MAX_SUPPORTED_VQS ]; -struct vdpa_callback event_cbs[MLX5_MAX_SUPPORTED_VQS +1 ]; +struct mlx5_vdpa_virtqueue *vqs; +struct vdpa_callback *event_cbs;/* Serialize vq resources creation and destruction. This is required * since memory map might change and we need to destroy and create @@ -1218,7 +1213,7 @@ static void suspend_vqs(struct mlx5_vdpa_net *ndev) {int i; -for (i =0 ; i <MLX5_MAX_SUPPORTED_VQS ; i++) +for (i =0 ; i < ndev->mvdev.max_vqs; i++)suspend_vq (ndev, &ndev->vqs[i]); }@@ -1244,8 +1239,14 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)void *in;int i, j;int err; +int num; - max_rqt =min_t (int,MLX5_MAX_SUPPORTED_VQS /2 , +if (!(ndev->mvdev.actual_features &BIT_ULL (VIRTIO_NET_F_MQ ))) + num =1 ; +else + num =le16_to_cpu (ndev->config.max_virtqueue_pairs); + + max_rqt =min_t (int,roundup_pow_of_two (num),1 <<MLX5_CAP_GEN (ndev->mvdev.mdev, log_max_rqt_size));if (max_rqt <1 )return -EOPNOTSUPP ;@@ -1262,7 +1263,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev)MLX5_SET (rqtc, rqtc, rqt_max_size, max_rqt); list =MLX5_ADDR_OF (rqtc, rqtc, rq_num[0 ]);for (i =0 , j =0 ; i < max_rqt; i++, j +=2 ) - list[i] =cpu_to_be32 (ndev->vqs[j % ndev->mvdev.max_vqs].virtq_id); + list[i] =cpu_to_be32 (ndev->vqs[j % (2 * num)].virtq_id);MLX5_SET (rqtc, rqtc, rqt_actual_size, max_rqt); err =mlx5_vdpa_create_rqt (&ndev->mvdev, in, inlen, &ndev->res.rqtn);@@ -2220,7 +2221,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)clear_vqs_ready (ndev);mlx5_vdpa_destroy_mr (&ndev->mvdev); ndev->mvdev.status =0 ; -memset (ndev->event_cbs,0 ,sizeof (ndev->event_cbs)); +memset (ndev->event_cbs,0 ,sizeof (*ndev->event_cbs) * (mvdev->max_vqs +1 )); ndev->mvdev.actual_features =0 ; ++mvdev->generation;if (MLX5_CAP_GEN (mvdev->mdev, umem_uid_0)) {@@ -2293,6 +2294,8 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev) }mlx5_vdpa_free_resources (&ndev->mvdev);mutex_destroy (&ndev->reslock); +kfree (ndev->event_cbs); +kfree (ndev->vqs); }static struct vdpa_notification_area mlx5_get_vq_notification (struct vdpa_device *vdev,u16 idx)@@ -2538,15 +2541,33 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,return -EOPNOTSUPP ; } -/* we save one virtqueue for control virtqueue should we require it */ max_vqs =MLX5_CAP_DEV_VDPA_EMULATION (mdev, max_num_virtio_queues); - max_vqs =min_t (u32, max_vqs,MLX5_MAX_SUPPORTED_VQS ); +if (max_vqs <2 ) { +dev_warn (mdev->device, +"%d virtqueues are supported. At least 2 are required\n" , + max_vqs); +return -EAGAIN ; + } + +if (add_config->mask &BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP )) { +if (add_config->net.max_vq_pairs > max_vqs /2 ) +return -EINVAL ; + max_vqs =min_t (u32, max_vqs,2 * add_config->net.max_vq_pairs); + }else { + max_vqs =2 ; + }drivers/vdpa/mlx5/net/mlx5_vnet.c static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, · line 2567
Quoted 10 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +6
-0ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops, name, false);if (IS_ERR (ndev))return PTR_ERR (ndev); + ndev->vqs =kcalloc (max_vqs,sizeof (*ndev->vqs),GFP_KERNEL ); + ndev->event_cbs =kcalloc (max_vqs +1 ,sizeof (*ndev->event_cbs),GFP_KERNEL ); +if (!ndev->vqs || !ndev->event_cbs) { + err = -ENOMEM ; + goto err_alloc; + }Clang warns:
drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:6: error: variable 'mvdev' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]if (!ndev->vqs || !ndev->event_cbs) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/vdpa/mlx5/net/mlx5_vnet.c:2660:14: note: uninitialized use occurs here put_device(&mvdev->vdev.dev); ^~~~~ drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:2: note: remove the 'if' if its condition is always false if (!ndev->vqs || !ndev->event_cbs) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:6: error: variable 'mvdev' is used uninitialized whenever '||' condition is true [-Werror,-Wsometimes-uninitialized] if (!ndev->vqs || !ndev->event_cbs) { ^~~~~~~~~~ drivers/vdpa/mlx5/net/mlx5_vnet.c:2660:14: note: uninitialized use occurs here put_device(&mvdev->vdev.dev); ^~~~~ drivers/vdpa/mlx5/net/mlx5_vnet.c:2574:6: note: remove the '||' if its condition is always false if (!ndev->vqs || !ndev->event_cbs) { ^~~~~~~~~~~~~ drivers/vdpa/mlx5/net/mlx5_vnet.c:2534:29: note: initialize the variable 'mvdev' to silence this warning struct mlx5_vdpa_dev *mvdev; ^ = NULL2 errors generated.
I was going to send a patch just moving "
err_alloc" right above "return err;" but I don't think that is a proper fix. I think this patch is going to result in memory leaks on theerr_mpfsanderr_mtupaths, asndev->vqsandndev->event_cbswill have been allocated but they are only cleaned up inmlx5_vdpa_free_resources(). Additionally, I don't think the results of these allocations should be checked together, because one could succeed and the other could fail, meaning one needs to be cleaned up while the other doesn't.Cheers,
NathanQuoted 12 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;@@ -2627,6 +2648,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,mlx5_mpfs_del_mac (pfmdev, config->mac); err_mtu:mutex_destroy (&ndev->reslock); +err_alloc:put_device (&mvdev->vdev.dev);return err; }@@ -2669,7 +2691,8 @@ static int mlx5v_probe(struct auxiliary_device *adev,
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c static int mlx5v_probe(struct auxiliary_device *adev, · line 2697
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +2
-1mgtdev->mgtdev.ops = &mdev_ops; mgtdev->mgtdev.device = mdev->device; mgtdev->mgtdev.id_table = id_table; - mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); + mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ) | +BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP ); mgtdev->madev = madev; err =vdpa_mgmtdev_register (&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Michael S. Tsirkin
maintainerRe: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 3 lines · Si-Wei Liu
It's unfortunate. Don't know why this series got pulled into linux-next prematurely. The code review is still on going and there were outstanding comments that hadn't been addressed yet.
Most patches got acked, and the merge window is closing. The only couple of issues seem to be with this specific patch, and I think I fixed them up.
Still - I can hold them if necessary. What do others think?
Signature · 1 line
MST
Re: [PATCH v7 07/14] vdpa/mlx5: Support configuring max data virtqueue
Quoted 9 lines · Michael S. Tsirkin
Quoted 3 lines · Si-Wei Liu
It's unfortunate. Don't know why this series got pulled into linux-next prematurely. The code review is still on going and there were outstanding comments that hadn't been addressed yet.
Most patches got acked, and the merge window is closing. The only couple of issues seem to be with this specific patch, and I think I fixed them up.
Still - I can hold them if necessary. What do others think?
Well, you could argue that I am not objective, but I think we should keep them since they address all interface related concerns raised and they work.
Quoted 4 lines
Signature · 2 lines
-- MST
A message that is not in the archive (sent off-list or not yet received): [email protected]
Si-Wei Liu
Reviewed-byRe: [PATCH v7 10/14] vdpa: Support reporting max device capabilities
Quoted 10 lines · Eli Cohen
Add
max_supported_vqsandsupported_featuresfields to structvdpa_mgmt_dev. Upstream drivers need to feel these values according to the device capabilities.These values are reported back in a netlink message when showing management devices.
Examples:
$ auxiliary/mlx5_core.sf.1:
Missing the exact 'vdpa mgmtdev show ...' command, otherwise:
Quoted 75 lines
supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORM$ vdpa -j mgmtdev show {"mgmtdev":{"auxiliary/mlx5_core.sf.1":{"supported_classes":["net"], \ "max_supported_vqs":257,"dev_features":["CSUM","GUEST_CSUM","MTU", \ "HOST_TSO4","HOST_TSO6","STATUS","CTRL_VQ","MQ","CTRL_MAC_ADDR", \ "VERSION_1","ACCESS_PLATFORM"]}}}$ vdpa -jp mgmtdev show { "mgmtdev": { "auxiliary/mlx5_core.sf.1": { "supported_classes": [ "net" ], "max_supported_vqs": 257, "dev_features": ["CSUM","GUEST_CSUM","MTU","HOST_TSO4", \ "HOST_TSO6","STATUS","CTRL_VQ","MQ", \ "CTRL_MAC_ADDR","VERSION_1","ACCESS_PLATFORM"] } } }Signed-off-by Eli Cohen <[email protected]>---
v6 -> v7:
1. Fix comment
2. Fix error flow
3. Add device featuresdrivers/vdpa/vdpa.c | 10 ++++++++++ include/linux/vdpa.h | 2 ++ include/uapi/linux/vdpa.h | 2 ++ 3 files changed, 14 insertions(+)drivers/vdpa/vdpa.c +10
-0@@ -514,6 +514,16 @@ static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *m err = -EMSGSIZE ; goto msg_err; } +if (nla_put_u32 (msg,VDPA_ATTR_DEV_MGMTDEV_MAX_VQS , + mdev->max_supported_vqs)) { + err = -EMSGSIZE ; + goto msg_err; + } +if (nla_put_u64_64bit (msg,VDPA_ATTR_DEV_SUPPORTED_FEATURES , + mdev->supported_features,VDPA_ATTR_PAD )) { + err = -EMSGSIZE ; + goto msg_err; + }genlmsg_end (msg, hdr);return 0 ;include/linux/vdpa.h +2
-0@@ -460,6 +460,8 @@ struct vdpa_mgmt_dev {const struct virtio_device_id *id_table;u64 config_attr_mask;struct list_head list; +u64 supported_features; +u32 max_supported_vqs; };int vdpa_mgmtdev_register (struct vdpa_mgmt_dev *mdev);include/uapi/linux/vdpa.h +0
-0
include/uapi/linux/vdpa.h enum vdpa_attr { · line 51
Quoted 8 lines
include/uapi/linux/vdpa.h +2
-0@@ -44,6 +44,8 @@ enum vdpa_attr {VDPA_ATTR_DEV_NET_CFG_MTU ,/* u16 */ VDPA_ATTR_DEV_NEGOTIATED_FEATURES ,/* u64 */ +VDPA_ATTR_DEV_MGMTDEV_MAX_VQS ,/* u32 */ +VDPA_ATTR_DEV_SUPPORTED_FEATURES ,/* u64 */ /* new attributes must be added above here */ VDPA_ATTR_MAX, };
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Si-Wei Liu
Reviewed-byRe: [PATCH v7 11/14] vdpa/mlx5: Report max device capabilities
Quoted 4 lines · Eli Cohen
Configure max supported virtqueues and features on the management device.
This info can be retrieved using:
Quoted 8 lines
$ vdpa mgmtdev show auxiliary/mlx5_core.sf.1: supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORMSigned-off-by Eli Cohen <[email protected]>
Quoted 61 lines
---
v6 -> v7:
1. Add supported featuresdrivers/vdpa/mlx5/net/mlx5_vnet.c | 35 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +20
-12@@ -1867,22 +1867,29 @@ static u64 mlx_to_vritio_features(u16 dev_features)return result; } +static u64 get_supported_features (struct mlx5_core_dev *mdev) +{ +u64 mlx_vdpa_features =0 ; +u16 dev_features; + + dev_features =MLX5_CAP_DEV_VDPA_EMULATION (mdev, device_features_bits_mask); + mlx_vdpa_features |=mlx_to_vritio_features (dev_features); +if (MLX5_CAP_DEV_VDPA_EMULATION (mdev, virtio_version_1_0)) + mlx_vdpa_features |=BIT_ULL (VIRTIO_F_VERSION_1 ); + mlx_vdpa_features |=BIT_ULL (VIRTIO_F_ACCESS_PLATFORM ); + mlx_vdpa_features |=BIT_ULL (VIRTIO_NET_F_CTRL_VQ ); + mlx_vdpa_features |=BIT_ULL (VIRTIO_NET_F_CTRL_MAC_ADDR ); + mlx_vdpa_features |=BIT_ULL (VIRTIO_NET_F_MQ ); + mlx_vdpa_features |=BIT_ULL (VIRTIO_NET_F_STATUS ); + mlx_vdpa_features |=BIT_ULL (VIRTIO_NET_F_MTU ); + +return mlx_vdpa_features; +} +static u64 mlx5_vdpa_get_device_features (struct vdpa_device *vdev) {struct mlx5_vdpa_dev *mvdev =to_mvdev (vdev);struct mlx5_vdpa_net *ndev =to_mlx5_vdpa_ndev (mvdev); -u16 dev_features; - - dev_features =MLX5_CAP_DEV_VDPA_EMULATION (mvdev->mdev, device_features_bits_mask); - ndev->mvdev.mlx_features |=mlx_to_vritio_features (dev_features); -if (MLX5_CAP_DEV_VDPA_EMULATION (mvdev->mdev, virtio_version_1_0)) - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_F_VERSION_1 ); - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_F_ACCESS_PLATFORM ); - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_NET_F_CTRL_VQ ); - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_NET_F_CTRL_MAC_ADDR ); - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_NET_F_MQ ); - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_NET_F_STATUS ); - ndev->mvdev.mlx_features |=BIT_ULL (VIRTIO_NET_F_MTU );print_features (mvdev, ndev->mvdev.mlx_features, false);return ndev->mvdev.mlx_features;@@ -2570,6 +2577,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, err = -ENOMEM ; goto err_alloc; } + ndev->mvdev.mlx_features = mgtdev->mgtdev.supported_features; ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev; mvdev->mdev = mdev;
drivers/vdpa/mlx5/net/mlx5_vnet.c static int mlx5v_probe(struct auxiliary_device *adev, · line 2711
Quoted 9 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +3
-0@@ -2695,6 +2703,9 @@ static int mlx5v_probe(struct auxiliary_device *adev, mgtdev->mgtdev.id_table = id_table; mgtdev->mgtdev.config_attr_mask =BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ) |BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MAX_VQP ); + mgtdev->mgtdev.max_supported_vqs = +MLX5_CAP_DEV_VDPA_EMULATION (mdev, max_num_virtio_queues) +1 ; + mgtdev->mgtdev.supported_features =get_supported_features (mdev); mgtdev->madev = madev; err =vdpa_mgmtdev_register (&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Jason Wang
Acked-byRe: [PATCH v7 11/14] vdpa/mlx5: Report max device capabilities
Quoted 14 lines · Si-Wei Liu
Quoted 11 lines · Eli Cohen
Configure max supported virtqueues and features on the management device.
This info can be retrieved using:$ vdpa mgmtdev show auxiliary/mlx5_core.sf.1: supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORM
Quoted 2 lines
Quoted 1 line
Signed-off-by Eli Cohen <[email protected]>Reviewed-by Si-Wei Liu<[email protected]>
Quoted 64 lines
Quoted 64 lines
---
v6 -> v7:
1. Add supported features
drivers/vdpa/mlx5/net/mlx5_vnet.c| 35 ++++++++++++++++++++-----------1 file changed, 23 insertions(+), 12 deletions(-)drivers/vdpa/mlx5/net/mlx5_vnet.c +18
-12@@ -1867,22 +1867,29 @@ static u64 mlx_to_vritio_features(u16 dev_features) return result; } +static u64 get_supported_features(struct mlx5_core_dev *mdev) +{ + u64 mlx_vdpa_features = 0; + u16 dev_features; + + dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mdev, device_features_bits_mask); + mlx_vdpa_features |= mlx_to_vritio_features(dev_features); + if (MLX5_CAP_DEV_VDPA_EMULATION(mdev, virtio_version_1_0)) + mlx_vdpa_features |= BIT_ULL(VIRTIO_F_VERSION_1); + mlx_vdpa_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM); + mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_VQ); + mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR); + mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MQ); + mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_STATUS); + mlx_vdpa_features |= BIT_ULL(VIRTIO_NET_F_MTU); + + return mlx_vdpa_features; +} + static u64 mlx5_vdpa_get_device_features(struct vdpa_device *vdev) { struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); - u16 dev_features; - - dev_features = MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, device_features_bits_mask); - ndev->mvdev.mlx_features |= mlx_to_vritio_features(dev_features); - if (MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, virtio_version_1_0)) - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_VERSION_1); - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_F_ACCESS_PLATFORM); - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_NET_F_CTRL_VQ); - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR); - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_NET_F_MQ); - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_NET_F_STATUS); - ndev->mvdev.mlx_features |= BIT_ULL(VIRTIO_NET_F_MTU);
print_features(mvdev, ndev->mvdev.mlx_features, false); returnndev->mvdev.mlx_features;drivers/vdpa/mlx5/net/mlx5_vnet.c +1
-0@@ -2570,6 +2577,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, err = -ENOMEM; goto err_alloc; } + ndev->mvdev.mlx_features = mgtdev->mgtdev.supported_features; ndev->mvdev.max_vqs = max_vqs; mvdev = &ndev->mvdev;
mvdev->mdev= mdev;drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0@@ -2695,6 +2703,9 @@ static int mlx5v_probe(struct auxiliary_device *adev,
Quoted 9 lines
Quoted 8 lines
drivers/vdpa/mlx5/net/mlx5_vnet.c +0
-0mgtdev->mgtdev.id_table = id_table;
mgtdev->mgtdev.config_attr_mask=BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)|BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);
+mgtdev->mgtdev.max_supported_vqs=
+MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues)+ 1; +mgtdev->mgtdev.supported_features=get_supported_features(mdev);mgtdev->madev= madev;
err =vdpa_mgmtdev_register(&mgtdev->mgtdev);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Jason Wang
Acked-byRe: [PATCH v7 04/14] vdpa: Read device configuration only if FEATURES_OK
Quoted 7 lines · Eli Cohen
Avoid reading device configuration during feature negotiation. Read device status and verify that
VIRTIO_CONFIG_S_FEATURES_OKis set.Protect the entire operation, including configuration read with
cf_mutexto ensure integrity of the results.Signed-off-by Eli Cohen <[email protected]>
Quoted 91 lines
---
v5 -> v6:
1. Usecf_mutexto serialize the entire operations--- drivers/vdpa/vdpa.c | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-)drivers/vdpa/vdpa.c +31
-12@@ -393,6 +393,21 @@ void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev) }EXPORT_SYMBOL_GPL (vdpa_mgmtdev_unregister); +static void vdpa_get_config_unlocked (struct vdpa_device *vdev, +unsigned int offset, +void *buf,unsigned int len) +{ +const struct vdpa_config_ops *ops = vdev->config; + +/* +* Config accesses aren't supposed to trigger before features are set. +* If it does happen we assume a legacy guest. +*/ +if (!vdev->features_valid) +vdpa_set_features (vdev,0 ); + ops->get_config (vdev, offset, buf, len); +} +/** * vdpa_get_config - Get one or more device configuration fields. * @vdev: vdpa device to operate on @@ -403,16 +418,8 @@ EXPORT_SYMBOL_GPL(vdpa_mgmtdev_unregister);void vdpa_get_config (struct vdpa_device *vdev,unsigned int offset,void *buf,unsigned int len) { -const struct vdpa_config_ops *ops = vdev->config; -mutex_lock (&vdev->cf_mutex); -/* -* Config accesses aren't supposed to trigger before features are set. -* If it does happen we assume a legacy guest. -*/ -if (!vdev->features_valid) -vdpa_set_features (vdev,0 ); - ops->get_config (vdev, offset, buf, len); +vdpa_get_config_unlocked (vdev, offset, buf, len);mutex_unlock (&vdev->cf_mutex); }EXPORT_SYMBOL_GPL (vdpa_get_config);@@ -813,7 +820,7 @@ static int vdpa_dev_net_config_fill(struct vdpa_device *vdev, struct sk_buff *msu64 features;u16 val_u16; -vdpa_get_config (vdev,0 , &config,sizeof (config)); +vdpa_get_config_unlocked (vdev,0 , &config,sizeof (config));if (nla_put (msg,VDPA_ATTR_DEV_NET_CFG_MACADDR ,sizeof (config.mac), config.mac))@@ -838,12 +845,23 @@ vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, {u32 device_id;void *hdr; +u8 status;int err; +mutex_lock (&vdev->cf_mutex); + status = vdev->config->get_status (vdev); +if (!(status &VIRTIO_CONFIG_S_FEATURES_OK )) { +NL_SET_ERR_MSG_MOD (extack,"Features negotiation not completed" ); + err = -EAGAIN ; + goto out; + } + hdr =genlmsg_put (msg, portid, seq, &vdpa_nl_family, flags,VDPA_CMD_DEV_CONFIG_GET ); -if (!hdr) -return -EMSGSIZE ; +if (!hdr) { + err = -EMSGSIZE ; + goto out; + }if (nla_put_string (msg,VDPA_ATTR_DEV_NAME ,dev_name (&vdev->dev))) { err = -EMSGSIZE ;@@ -867,11 +885,14 @@ vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid,if (err) goto msg_err; +mutex_unlock (&vdev->cf_mutex);
drivers/vdpa/vdpa.c vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, · line 898
Quoted 10 lines
drivers/vdpa/vdpa.c +2
-0genlmsg_end (msg, hdr);return 0 ; msg_err:genlmsg_cancel (msg, hdr); +out: +mutex_unlock (&vdev->cf_mutex);return err; }
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Jason Wang
Acked-byRe: [PATCH v7 08/14] vdpa: Add support for returning device configuration information
Quoted 33 lines · Eli Cohen
Add netlink attribute to store the negotiated features. This can be used by userspace to get the current state of the vdpa instance.
Examples:
$ vdpa dev config show vdpa-a vdpa-a: mac 00:00:00:00:88:88 link up link_announce false max_vq_pairs 16 mtu 1500 negotiated_features CSUM GUEST_CSUM MTU MAC HOST_TSO4 HOST_TSO6 STATUS \ CTRL_VQ MQ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORM$ vdpa -j dev config show vdpa-a {"config":{"vdpa-a":{"mac":"00:00:00:00:88:88","link ":"up","link_announce":false, \ "max_vq_pairs":16,"mtu":1500,"negotiated_features":["CSUM","GUEST_CSUM","MTU","MAC", \ "HOST_TSO4","HOST_TSO6","STATUS","CTRL_VQ","MQ","CTRL_MAC_ADDR","VERSION_1", \ "ACCESS_PLATFORM"]}}}$ vdpa -jp dev config show vdpa-a { "config": { "vdpa-a": { "mac": "00:00:00:00:88:88", "link ": "up", "link_announce ": false, "max_vq_pairs": 16, "mtu": 1500, "negotiated_features": [ "CSUM","GUEST_CSUM","MTU","MAC","HOST_TSO4","HOST_TSO6","STATUS","CTRL_VQ","MQ", \ "CTRL_MAC_ADDR","VERSION_1","ACCESS_PLATFORM" ] } } }
Quoted 1 line
Signed-off-by Eli Cohen <[email protected]>
Quoted 34 lines
--- drivers/vdpa/vdpa.c | 3 +++ include/uapi/linux/vdpa.h | 4 ++++ 2 files changed, 7 insertions(+)drivers/vdpa/vdpa.c +3
-0@@ -846,6 +846,9 @@ static int vdpa_dev_net_config_fill(struct vdpa_device *vdev, struct sk_buff *msreturn -EMSGSIZE ; features = vdev->config->get_driver_features (vdev); +if (nla_put_u64_64bit (msg,VDPA_ATTR_DEV_NEGOTIATED_FEATURES , features, +VDPA_ATTR_PAD )) +return -EMSGSIZE ;return vdpa_dev_net_mq_config_fill (vdev, msg, features, &config); }include/uapi/linux/vdpa.h +3
-0@@ -23,6 +23,9 @@ enum vdpa_command {enum vdpa_attr {VDPA_ATTR_UNSPEC , +/* Pad attribute for 64b alignment */ +VDPA_ATTR_PAD =VDPA_ATTR_UNSPEC , +/* bus name (optional) + dev name together make the parent device handle */ VDPA_ATTR_MGMTDEV_BUS_NAME ,/* string */ VDPA_ATTR_MGMTDEV_DEV_NAME ,/* string */
include/uapi/linux/vdpa.h enum vdpa_attr { · line 49
Quoted 7 lines
include/uapi/linux/vdpa.h +1
-0@@ -40,6 +43,7 @@ enum vdpa_attr {VDPA_ATTR_DEV_NET_CFG_MAX_VQP ,/* u16 */ VDPA_ATTR_DEV_NET_CFG_MTU ,/* u16 */ +VDPA_ATTR_DEV_NEGOTIATED_FEATURES ,/* u64 */ /* new attributes must be added above here */ VDPA_ATTR_MAX, };
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Jason Wang
Acked-byRe: [PATCH v7 12/14] vdpa/vdpa_sim: Configure max supported virtqueues
Quoted 3 lines · Eli Cohen
Configure max supported virtqueues on the management device.
Signed-off-by Eli Cohen <[email protected]>
Quoted 9 lines
--- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 1 + 1 file changed, 1 insertion(+)drivers/vdpa/vdpa_sim/vdpa_sim_net.c +0
-0
drivers/vdpa/vdpa_sim/vdpa_sim_net.c static struct vdpa_mgmt_dev mgmt_dev = { · line 197
Quoted 7 lines
drivers/vdpa/vdpa_sim/vdpa_sim_net.c +1
-0@@ -191,6 +191,7 @@ static struct vdpa_mgmt_dev mgmt_dev = { .ops = &vdpasim_net_mgmtdev_ops, .config_attr_mask = (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR | 1 << VDPA_ATTR_DEV_NET_CFG_MTU), + .max_supported_vqs = VDPASIM_NET_VQ_NUM, };static int __init vdpasim_net_init (void )
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Jason Wang
Acked-byRe: [PATCH v7 13/14] vdpa: Use BIT_ULL for bit operations
Quoted 7 lines · Eli Cohen
All masks in this file are 64 bits. Change BIT to
BIT_ULL.Other occurences use (1 << val) which yields a 32 bit value. Change them to use
BIT_ULLtoo.Reviewed-by Si-Wei Liu <[email protected]>Signed-off-by Eli Cohen <[email protected]>
Quoted 37 lines
--- drivers/vdpa/vdpa.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)drivers/vdpa/vdpa.c +5
-5@@ -590,9 +590,9 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)return msg->len; } -#define VDPA_DEV_NET_ATTRS_MASK ((1 << VDPA_ATTR_DEV_NET_CFG_MACADDR) | \ - (1 << VDPA_ATTR_DEV_NET_CFG_MTU) | \ - (1 << VDPA_ATTR_DEV_NET_CFG_MAX_VQP)) +#define VDPA_DEV_NET_ATTRS_MASK (BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR) | \ + BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MTU) | \ + BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP))static int vdpa_nl_cmd_dev_add_set_doit (struct sk_buff *skb,struct genl_info *info) {@@ -611,12 +611,12 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *iif (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR ]) { macaddr =nla_data (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MACADDR ]);memcpy (config.net.mac, macaddr,sizeof (config.net.mac)); - config.mask |= (1 <<VDPA_ATTR_DEV_NET_CFG_MACADDR ); + config.mask |=BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MACADDR ); }if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU ]) { config.net.mtu =nla_get_u16 (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MTU ]); - config.mask |= (1 <<VDPA_ATTR_DEV_NET_CFG_MTU ); + config.mask |=BIT_ULL (VDPA_ATTR_DEV_NET_CFG_MTU ); }if (nl_attrs[VDPA_ATTR_DEV_NET_CFG_MAX_VQP ]) { config.net.max_vq_pairs =
drivers/vdpa/vdpa.c static int vdpa_dev_net_mq_config_fill(struct vdpa_device *vdev, · line 834
Quoted 8 lines
drivers/vdpa/vdpa.c +1
-1@@ -828,7 +828,7 @@ static int vdpa_dev_net_mq_config_fill(struct vdpa_device *vdev, {u16 val_u16; -if ((features & (1ULL <<VIRTIO_NET_F_MQ )) ==0 ) +if ((features &BIT_ULL (VIRTIO_NET_F_MQ )) ==0 )return 0 ; val_u16 =le16_to_cpu (config->max_virtqueue_pairs);
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Jason Wang
Acked-byRe: [PATCH v7 14/14] vdpa/vdpa_sim_net: Report max device capabilities
Quoted 10 lines · Eli Cohen
Configure max supported virtqueues features on the management device. This info can be retrieved using:
$ vdpa mgmtdev show vdpasim_net: supported_classes net max_supported_vqs 2 dev_features MAC ANY_LAYOUT VERSION_1 ACCESS_PLATFORMSigned-off-by Eli Cohen <[email protected]>
Quoted 9 lines
--- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 1 + 1 file changed, 1 insertion(+)drivers/vdpa/vdpa_sim/vdpa_sim_net.c +0
-0
drivers/vdpa/vdpa_sim/vdpa_sim_net.c static struct vdpa_mgmt_dev mgmt_dev = { · line 198
Quoted 7 lines
drivers/vdpa/vdpa_sim/vdpa_sim_net.c +1
-0@@ -192,6 +192,7 @@ static struct vdpa_mgmt_dev mgmt_dev = { .config_attr_mask = (1 << VDPA_ATTR_DEV_NET_CFG_MACADDR | 1 << VDPA_ATTR_DEV_NET_CFG_MTU), .max_supported_vqs = VDPASIM_NET_VQ_NUM, + .supported_features = VDPASIM_NET_FEATURES, };static int __init vdpasim_net_init (void )
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Michael S. Tsirkin
maintainerRe: [PATCH v7 00/14] Allow for configuring max number of virtqueue pairs
In reply to a message not in the archiveQuoted 3 lines · Eli Cohen
Allow the user to configure the max number of virtqueue pairs for a vdpa instance. The user can then control the actual number of virtqueue pairs using ethtool.
So I put a version of this in linux-next, but I had to squash in some bugfixes, and resolve some conflicts. Eli, please take a look and let me know whether it looks sane. If not pls post a new version.
Jason, what is your take on merging this now? Si-wei here seems to want to defer, but OTOH it's up to v7 already, most patches are acked and most comments look like minor improvement suggestions to me.
Quoted 45 lines
Example, set number of VQPs to 2:
$ ethtool -L ens1 combined 2A user can check the max supported virtqueues for a management device by running:
$ $ vdpa mgmtdev show auxiliary/mlx5_core.sf.1: supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORMand refer to this value when adding a device.
To create a device with a max of 5 VQPs:
vdpa dev add name vdpa-a mgmtdev auxiliary/mlx5_core.sf.1max_vqp5Please note that for patches that were changed I removed "Reviewed-by" and "Acked-by".
v6 -> v7:
1. Make use ofcf_mutexfor serializing netlink set/get with other calls.
2. Some fixes (See in each patch)
3. Add patch forvdpa_simto report supported features
4. "Reviewed-by" and "Acked-by" removed from patch 0007 since it had slightly changed.Eli Cohen (14):
vdpa: Provide interface to read driver features
vdpa/mlx5: Distribute RX virtqueues in RQT object
vdpa: Sync calls set/get config/status withcf_mutex
vdpa: Read device configuration only ifFEATURES_OK
vdpa: Allow to configure max data virtqueues
vdpa/mlx5: Fixconfig_attr_maskassignment
vdpa/mlx5: Support configuring max data virtqueue
vdpa: Add support for returning device configuration information vdpa/mlx5: Restorecur_num_vqsin case of failure inchange_num_qps()
vdpa: Support reporting max device capabilities
vdpa/mlx5: Report max device capabilities
vdpa/vdpa_sim: Configure max supported virtqueues
vdpa: UseBIT_ULLfor bit operations
vdpa/vdpa_sim_net: Report max device capabilities
Quoted 16 lines
drivers/vdpa/alibaba/eni_vdpa.c | 16 +++- drivers/vdpa/ifcvf/ifcvf_main.c | 16 +++- drivers/vdpa/mlx5/net/mlx5_vnet.c | 134 ++++++++++++++++----------- drivers/vdpa/vdpa.c | 100 ++++++++++++++++---- drivers/vdpa/vdpa_sim/vdpa_sim.c | 21 +++-- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 2 + drivers/vdpa/vdpa_user/vduse_dev.c | 16 +++- drivers/vdpa/virtio_pci/vp_vdpa.c | 16 +++- drivers/vhost/vdpa.c | 11 +-- drivers/virtio/virtio_vdpa.c | 7 +- include/linux/vdpa.h | 36 +++++-- include/uapi/linux/vdpa.h | 6 ++ 12 files changed, 271 insertions(+), 110 deletions(-)Signature · 1 line
2.34.1
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 00/14] Allow for configuring max number of virtqueue pairs
Quoted 6 lines · Michael S. Tsirkin
Quoted 3 lines · Eli Cohen
Allow the user to configure the max number of virtqueue pairs for a vdpa instance. The user can then control the actual number of virtqueue pairs using ethtool.
Quoted 7 lines
So I put a version of this in linux-next, but I had to squash in some bugfixes, and resolve some conflicts. Eli, please take a look and let me know whether it looks sane. If not pls post a new version.
Jason, what is your take on merging this now? Si-wei here seems to want to defer, but OTOH it's up to v7 already, most patches are acked and most comments look like minor improvement suggestions to me.
I think we can merge them and send patches on top to fix issues if needed.
Thanks
Quoted 60 lines
Quoted 60 lines
Example, set number of VQPs to 2:
$ ethtool -L ens1 combined 2A user can check the max supported virtqueues for a management device by running:
$ $ vdpa mgmtdev show auxiliary/mlx5_core.sf.1: supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORMand refer to this value when adding a device.
To create a device with a max of 5 VQPs:
vdpa dev add name vdpa-a mgmtdev auxiliary/mlx5_core.sf.1max_vqp5Please note that for patches that were changed I removed "Reviewed-by" and "Acked-by".
v6 -> v7:
1. Make use ofcf_mutexfor serializing netlink set/get with other calls.
2. Some fixes (See in each patch)
3. Add patch forvdpa_simto report supported features
4. "Reviewed-by" and "Acked-by" removed from patch 0007 since it had slightly changed.Eli Cohen (14):
vdpa: Provide interface to read driver features
vdpa/mlx5: Distribute RX virtqueues in RQT object
vdpa: Sync calls set/get config/status withcf_mutex
vdpa: Read device configuration only ifFEATURES_OK
vdpa: Allow to configure max data virtqueues
vdpa/mlx5: Fixconfig_attr_maskassignment
vdpa/mlx5: Support configuring max data virtqueue
vdpa: Add support for returning device configuration information vdpa/mlx5: Restorecur_num_vqsin case of failure inchange_num_qps()
vdpa: Support reporting max device capabilities
vdpa/mlx5: Report max device capabilities
vdpa/vdpa_sim: Configure max supported virtqueues
vdpa: UseBIT_ULLfor bit operations
vdpa/vdpa_sim_net: Report max device capabilitiesdrivers/vdpa/alibaba/eni_vdpa.c | 16 +++- drivers/vdpa/ifcvf/ifcvf_main.c | 16 +++- drivers/vdpa/mlx5/net/mlx5_vnet.c | 134 ++++++++++++++++----------- drivers/vdpa/vdpa.c | 100 ++++++++++++++++---- drivers/vdpa/vdpa_sim/vdpa_sim.c | 21 +++-- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 2 + drivers/vdpa/vdpa_user/vduse_dev.c | 16 +++- drivers/vdpa/virtio_pci/vp_vdpa.c | 16 +++- drivers/vhost/vdpa.c | 11 +-- drivers/virtio/virtio_vdpa.c | 7 +- include/linux/vdpa.h | 36 +++++-- include/uapi/linux/vdpa.h | 6 ++ 12 files changed, 271 insertions(+), 110 deletions(-)
Quoted 3 lines
Quoted 2 lines
--
2.34.1
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v7 00/14] Allow for configuring max number of virtqueue pairs
In reply to Michael S. TsirkinQuoted 11 lines · Michael S. Tsirkin
Quoted 3 lines · Eli Cohen
Allow the user to configure the max number of virtqueue pairs for a vdpa instance. The user can then control the actual number of virtqueue pairs using ethtool.
So I put a version of this in linux-next, but I had to squash in some bugfixes, and resolve some conflicts. Eli, please take a look and let me know whether it looks sane. If not pls post a new version.
Jason, what is your take on merging this now? Si-wei here seems to want to defer, but OTOH it's up to v7 already, most patches are acked and most comments look like minor improvement suggestions to me.
Sure, no worries. I thought maybe it's just me that cares about the completeness and correctness of this series. When I did review for v6 I also thought v7 might be the last shot, but it turned out there's outstanding comment missed to address and other issues due to last minute fix. It's definitely your call to pull it or not. I'm satisfied with all aspects of the uAPI change for this series in terms of the expectation set.
If you can help fix up the needless change to API vdpa_set_features() for "[PATCH v7 05/14] vdpa: Allow to configure max data virtqueues" I would much appreciate it. Or Eli can post a fix for that together with other issues on top, given it was very easy to lose track of these similar comments during the previous rounds of my review.
Thanks,
-Siwei
Quoted 60 lines
Quoted 60 lines
Example, set number of VQPs to 2:
$ ethtool -L ens1 combined 2A user can check the max supported virtqueues for a management device by running:
$ $ vdpa mgmtdev show auxiliary/mlx5_core.sf.1: supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORMand refer to this value when adding a device.
To create a device with a max of 5 VQPs:
vdpa dev add name vdpa-a mgmtdev auxiliary/mlx5_core.sf.1max_vqp5Please note that for patches that were changed I removed "Reviewed-by" and "Acked-by".
v6 -> v7:
1. Make use ofcf_mutexfor serializing netlink set/get with other calls.
2. Some fixes (See in each patch)
3. Add patch forvdpa_simto report supported features
4. "Reviewed-by" and "Acked-by" removed from patch 0007 since it had slightly changed.Eli Cohen (14):
vdpa: Provide interface to read driver features vdpa/mlx5: Distribute RX virtqueues in RQT object
vdpa: Sync calls set/get config/status withcf_mutex
vdpa: Read device configuration only ifFEATURES_OK
vdpa: Allow to configure max data virtqueues
vdpa/mlx5: Fixconfig_attr_maskassignment
vdpa/mlx5: Support configuring max data virtqueue
vdpa: Add support for returning device configuration information vdpa/mlx5: Restorecur_num_vqsin case of failure inchange_num_qps()
vdpa: Support reporting max device capabilities vdpa/mlx5: Report max device capabilities
vdpa/vdpa_sim: Configure max supported virtqueues
vdpa: UseBIT_ULLfor bit operations
vdpa/vdpa_sim_net: Report max device capabilitiesdrivers/vdpa/alibaba/eni_vdpa.c | 16 +++- drivers/vdpa/ifcvf/ifcvf_main.c | 16 +++- drivers/vdpa/mlx5/net/mlx5_vnet.c | 134 ++++++++++++++++----------- drivers/vdpa/vdpa.c | 100 ++++++++++++++++---- drivers/vdpa/vdpa_sim/vdpa_sim.c | 21 +++-- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 2 + drivers/vdpa/vdpa_user/vduse_dev.c | 16 +++- drivers/vdpa/virtio_pci/vp_vdpa.c | 16 +++- drivers/vhost/vdpa.c | 11 +-- drivers/virtio/virtio_vdpa.c | 7 +- include/linux/vdpa.h | 36 +++++-- include/uapi/linux/vdpa.h | 6 ++ 12 files changed, 271 insertions(+), 110 deletions(-)
Quoted 2 lines
Quoted 2 lines
Signature · 1 line
2.34.1
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v7 00/14] Allow for configuring max number of virtqueue pairs
Quoted 5 lines · Eli Cohen
Quoted 4 lines · Michael S. Tsirkin
Quoted 3 lines · Eli Cohen
Allow the user to configure the max number of virtqueue pairs for a vdpa instance. The user can then control the actual number of virtqueue pairs using ethtool.
Quoted 7 lines
Quoted 4 lines
So I put a version of this in linux-next, but I had to squash in some bugfixes, and resolve some conflicts. Eli, please take a look and let me know whether it looks sane. If not pls post a new version.
I see you squashed two fixes.
There was one more comment from Si-Wei which I addressed by sending a distinct patch titled "vdpa: Protect vdpa reset withcf_mutex".
Sorry, but I did not see this new patch that addressed reset. Please copy me when you get it (re-)posted.
-Siwei
Quoted 69 lines
It was not reviewed yet but maybe you can squash it on patch 0005 after it has been reviewed.
Quoted 65 lines
Jason, what is your take on merging this now? Si-wei here seems to want to defer, but OTOH it's up to v7 already, most patches are acked and most comments look like minor improvement suggestions to me.
Quoted 61 lines
Example, set number of VQPs to 2:
$ ethtool -L ens1 combined 2A user can check the max supported virtqueues for a management device by running:
$ $ vdpa mgmtdev show auxiliary/mlx5_core.sf.1: supported_classes net max_supported_vqs 257 dev_features CSUM GUEST_CSUM MTU HOST_TSO4 HOST_TSO6 STATUS CTRL_VQ MQ \ CTRL_MAC_ADDR VERSION_1 ACCESS_PLATFORMand refer to this value when adding a device.
To create a device with a max of 5 VQPs:
vdpa dev add name vdpa-a mgmtdev auxiliary/mlx5_core.sf.1max_vqp5Please note that for patches that were changed I removed "Reviewed-by" and "Acked-by".
v6 -> v7:
1. Make use ofcf_mutexfor serializing netlink set/get with other calls.
2. Some fixes (See in each patch)
3. Add patch forvdpa_simto report supported features
4. "Reviewed-by" and "Acked-by" removed from patch 0007 since it had slightly changed.Eli Cohen (14):
vdpa: Provide interface to read driver features vdpa/mlx5: Distribute RX virtqueues in RQT object
vdpa: Sync calls set/get config/status withcf_mutex
vdpa: Read device configuration only ifFEATURES_OK
vdpa: Allow to configure max data virtqueues
vdpa/mlx5: Fixconfig_attr_maskassignment
vdpa/mlx5: Support configuring max data virtqueue
vdpa: Add support for returning device configuration information vdpa/mlx5: Restorecur_num_vqsin case of failure inchange_num_qps()
vdpa: Support reporting max device capabilities vdpa/mlx5: Report max device capabilities
vdpa/vdpa_sim: Configure max supported virtqueues
vdpa: UseBIT_ULLfor bit operations
vdpa/vdpa_sim_net: Report max device capabilitiesdrivers/vdpa/alibaba/eni_vdpa.c | 16 +++- drivers/vdpa/ifcvf/ifcvf_main.c | 16 +++- drivers/vdpa/mlx5/net/mlx5_vnet.c | 134 ++++++++++++++++----------- drivers/vdpa/vdpa.c | 100 ++++++++++++++++---- drivers/vdpa/vdpa_sim/vdpa_sim.c | 21 +++-- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 2 + drivers/vdpa/vdpa_user/vduse_dev.c | 16 +++- drivers/vdpa/virtio_pci/vp_vdpa.c | 16 +++- drivers/vhost/vdpa.c | 11 +-- drivers/virtio/virtio_vdpa.c | 7 +- include/linux/vdpa.h | 36 +++++-- include/uapi/linux/vdpa.h | 6 ++ 12 files changed, 271 insertions(+), 110 deletions(-)Signature · 1 line
2.34.1
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization