Message ID | 1651812874-31967-6-git-send-email-si-wei.liu@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vhost-vdpa multiqueue fixes | expand |
On Thu, May 05, 2022 at 09:54:33PM -0700, Si-Wei Liu wrote: >The vhost_vdpa_one_time_request() branch in >vhost_vdpa_set_backend_cap() incorrectly sends down >ioctls on vhost_dev with non-zero index. This may >end up with multiple VHOST_SET_BACKEND_FEATURES >ioctl calls sent down on the vhost-vdpa fd that is >shared between all these vhost_dev's. > >To fix it, send down ioctl only once via the first >vhost_dev with index 0. For more readibility of >code, vhost_vdpa_one_time_request() is renamed to >vhost_vdpa_first_dev() with polarity flipped. Sorry for being late, you may have already discussed this, but IMHO it would be better to split this patch into two: - fix the problem in vhost_vdpa_set_backend_cap() - change name and polarity of vhost_vdpa_one_time_request() Thanks, Stefano >This call is only applicable to the request that >performs operation before setting up queues, and >usually at the beginning of operation. Document >the requirement for it in place. > >Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com> >Acked-by: Jason Wang <jasowang@redhat.com> >Acked-by: Eugenio Pérez <eperezma@redhat.com> >--- > hw/virtio/vhost-vdpa.c | 23 +++++++++++++++-------- > 1 file changed, 15 insertions(+), 8 deletions(-) > >diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c >index 8adf7c0..fd1268e 100644 >--- a/hw/virtio/vhost-vdpa.c >+++ b/hw/virtio/vhost-vdpa.c >@@ -366,11 +366,18 @@ static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v) > v->iova_range.last); > } > >-static bool vhost_vdpa_one_time_request(struct vhost_dev *dev) >+/* >+ * The use of this function is for requests that only need to be >+ * applied once. Typically such request occurs at the beginning >+ * of operation, and before setting up queues. It should not be >+ * used for request that performs operation until all queues are >+ * set, which would need to check dev->vq_index_end instead. >+ */ >+static bool vhost_vdpa_first_dev(struct vhost_dev *dev) > { > struct vhost_vdpa *v = dev->opaque; > >- return v->index != 0; >+ return v->index == 0; > } > > static int vhost_vdpa_get_dev_features(struct vhost_dev *dev, >@@ -451,7 +458,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) > > vhost_vdpa_get_iova_range(v); > >- if (vhost_vdpa_one_time_request(dev)) { >+ if (!vhost_vdpa_first_dev(dev)) { > return 0; > } > >@@ -594,7 +601,7 @@ static int vhost_vdpa_memslots_limit(struct vhost_dev *dev) > static int vhost_vdpa_set_mem_table(struct vhost_dev *dev, > struct vhost_memory *mem) > { >- if (vhost_vdpa_one_time_request(dev)) { >+ if (!vhost_vdpa_first_dev(dev)) { > return 0; > } > >@@ -623,7 +630,7 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev, > struct vhost_vdpa *v = dev->opaque; > int ret; > >- if (vhost_vdpa_one_time_request(dev)) { >+ if (!vhost_vdpa_first_dev(dev)) { > return 0; > } > >@@ -665,7 +672,7 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) > > features &= f; > >- if (vhost_vdpa_one_time_request(dev)) { >+ if (vhost_vdpa_first_dev(dev)) { > r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features); > if (r) { > return -EFAULT; >@@ -1118,7 +1125,7 @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, > struct vhost_log *log) > { > struct vhost_vdpa *v = dev->opaque; >- if (v->shadow_vqs_enabled || vhost_vdpa_one_time_request(dev)) { >+ if (v->shadow_vqs_enabled || !vhost_vdpa_first_dev(dev)) { > return 0; > } > >@@ -1240,7 +1247,7 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev, > > static int vhost_vdpa_set_owner(struct vhost_dev *dev) > { >- if (vhost_vdpa_one_time_request(dev)) { >+ if (!vhost_vdpa_first_dev(dev)) { > return 0; > } > >-- >1.8.3.1 >
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c index 8adf7c0..fd1268e 100644 --- a/hw/virtio/vhost-vdpa.c +++ b/hw/virtio/vhost-vdpa.c @@ -366,11 +366,18 @@ static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v) v->iova_range.last); } -static bool vhost_vdpa_one_time_request(struct vhost_dev *dev) +/* + * The use of this function is for requests that only need to be + * applied once. Typically such request occurs at the beginning + * of operation, and before setting up queues. It should not be + * used for request that performs operation until all queues are + * set, which would need to check dev->vq_index_end instead. + */ +static bool vhost_vdpa_first_dev(struct vhost_dev *dev) { struct vhost_vdpa *v = dev->opaque; - return v->index != 0; + return v->index == 0; } static int vhost_vdpa_get_dev_features(struct vhost_dev *dev, @@ -451,7 +458,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) vhost_vdpa_get_iova_range(v); - if (vhost_vdpa_one_time_request(dev)) { + if (!vhost_vdpa_first_dev(dev)) { return 0; } @@ -594,7 +601,7 @@ static int vhost_vdpa_memslots_limit(struct vhost_dev *dev) static int vhost_vdpa_set_mem_table(struct vhost_dev *dev, struct vhost_memory *mem) { - if (vhost_vdpa_one_time_request(dev)) { + if (!vhost_vdpa_first_dev(dev)) { return 0; } @@ -623,7 +630,7 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev, struct vhost_vdpa *v = dev->opaque; int ret; - if (vhost_vdpa_one_time_request(dev)) { + if (!vhost_vdpa_first_dev(dev)) { return 0; } @@ -665,7 +672,7 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) features &= f; - if (vhost_vdpa_one_time_request(dev)) { + if (vhost_vdpa_first_dev(dev)) { r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features); if (r) { return -EFAULT; @@ -1118,7 +1125,7 @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, struct vhost_log *log) { struct vhost_vdpa *v = dev->opaque; - if (v->shadow_vqs_enabled || vhost_vdpa_one_time_request(dev)) { + if (v->shadow_vqs_enabled || !vhost_vdpa_first_dev(dev)) { return 0; } @@ -1240,7 +1247,7 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev, static int vhost_vdpa_set_owner(struct vhost_dev *dev) { - if (vhost_vdpa_one_time_request(dev)) { + if (!vhost_vdpa_first_dev(dev)) { return 0; }