@samitouri / QOSamiQemu / commits / 44c8f42d58

vhost-user: rework enabling vrings

We call the handler almost the same way in three places: - cryptodev-vhost.c - vhost_net.c - vhost.c The only difference, is that in vhost.c we don't try to call the handler for old vhost-user (when VHOST_USER_F_PROTOCOL_FEATURES is not supported). cryptodev-vhost and vhost_net code will just fail in this case. Probably they were developed only for newer vhost-user. Anyway, it doesn't seem correct to rely on this error path, if these devices want to check, that they don't communicate to old vhost-user protocol, they should do that earlier. Let's create the common helper, to call .vhost_set_vring_enable and use in all three places. For vhost-user let's just always skip enable/disable if it's unsupported. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Reviewed-by: Daniil Tatianin <d-tatianin@yandex-team.ru> Reviewed-by: Raphael Norwitz <raphael.s.norwitz@gmail.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Tested-by: Lei Yang <leiyang@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260420200339.708640-2-vsementsov@yandex-team.ru>

Vladimir Sementsov-Ogievskiy committed Apr 20, 2026 at 23:03 UTC 44c8f42d5824ab652ddeedb79851fa72d2af7be1
5 files changed +17 -35
backends/cryptodev-vhost.c
+1 -7
@@ -152,7 +152,6 @@ vhost_set_vring_enable(CryptoDevBackendClient *cc,
152 {
153 CryptoDevBackendVhost *crypto =
154 cryptodev_get_vhost(cc, b, queue);
155 - const VhostOps *vhost_ops;
155
156 cc->vring_enable = enable;
157
@@ -160,12 +159,7 @@ vhost_set_vring_enable(CryptoDevBackendClient *cc,
159 return 0;
160 }
161
163 - vhost_ops = crypto->dev.vhost_ops;
164 - if (vhost_ops->vhost_set_vring_enable) {
165 - return vhost_ops->vhost_set_vring_enable(&crypto->dev, enable);
166 - }
167 -
168 - return 0;
162 + return vhost_dev_set_vring_enable(&crypto->dev, enable);
163 }
164
165 int cryptodev_vhost_start(VirtIODevice *dev, int total_queues)
hw/net/vhost_net.c
+1 -6
@@ -587,7 +587,6 @@ VHostNetState *get_vhost_net(NetClientState *nc)
587 int vhost_net_set_vring_enable(NetClientState *nc, int enable)
588 {
589 VHostNetState *net = get_vhost_net(nc);
590 - const VhostOps *vhost_ops = net->dev.vhost_ops;
590
591 /*
592 * vhost-vdpa network devices need to enable dataplane virtqueues after
@@ -601,11 +600,7 @@ int vhost_net_set_vring_enable(NetClientState *nc, int enable)
600
601 nc->vring_enable = enable;
602
604 - if (vhost_ops && vhost_ops->vhost_set_vring_enable) {
605 - return vhost_ops->vhost_set_vring_enable(&net->dev, enable);
606 - }
607 -
608 - return 0;
603 + return vhost_dev_set_vring_enable(&net->dev, enable);
604 }
605
606 int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
hw/virtio/vhost-user.c
+6 -1
@@ -1230,7 +1230,12 @@ static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
1230 int i;
1231
1232 if (!virtio_has_feature(dev->features, VHOST_USER_F_PROTOCOL_FEATURES)) {
1233 - return -EINVAL;
1233 + /*
1234 + * For vhost-user devices, if VHOST_USER_F_PROTOCOL_FEATURES has not
1235 + * been negotiated, the rings start directly in the enabled state,
1236 + * and can't be disabled.
1237 + */
1238 + return 0;
1239 }
1240
1241 for (i = 0; i < dev->nvqs; ++i) {
hw/virtio/vhost.c
-21
@@ -2078,27 +2078,6 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
2078 return 0;
2079 }
2080
2081 -static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
2082 -{
2083 - if (!hdev->vhost_ops->vhost_set_vring_enable) {
2084 - return 0;
2085 - }
2086 -
2087 - /*
2088 - * For vhost-user devices, if VHOST_USER_F_PROTOCOL_FEATURES has not
2089 - * been negotiated, the rings start directly in the enabled state, and
2090 - * .vhost_set_vring_enable callback will fail since
2091 - * VHOST_USER_SET_VRING_ENABLE is not supported.
2092 - */
2093 - if (hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER &&
2094 - !virtio_has_feature(hdev->backend_features,
2095 - VHOST_USER_F_PROTOCOL_FEATURES)) {
2096 - return 0;
2097 - }
2098 -
2099 - return hdev->vhost_ops->vhost_set_vring_enable(hdev, enable);
2100 -}
2101 -
2081 /*
2082 * Host notifiers must be enabled at this point.
2083 *
include/hw/virtio/vhost.h
+9
@@ -215,6 +215,15 @@ static inline bool vhost_dev_is_started(struct vhost_dev *hdev)
215 return hdev->started;
216 }
217
218 +static inline int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
219 +{
220 + if (!hdev->vhost_ops->vhost_set_vring_enable) {
221 + return 0;
222 + }
223 +
224 + return hdev->vhost_ops->vhost_set_vring_enable(hdev, enable);
225 +}
226 +
227 /**
228 * vhost_dev_start() - start the vhost device
229 * @hdev: common vhost_dev structure