vdpa: fix vhost-vdpa suspended state not be shared
When stopping a vhost-vdpa device, only the first queue pair is marked as suspended,
while the remaining queues are not updated to the suspended state.
As a result, when stopping a multi-queue vhost-vdpa device,
the following error message will be printed.
qemu-system-x86_64:vhost VQ 2 ring restore failed: -1: Operation not permitted (1)
qemu-system-x86_64:vhost VQ 3 ring restore failed: -1: Operation not permitted (1)
So move v->suspended to v->shared, and then all the vhost_vdpa devices cannot
have different suspended states.
Fixes: 0bb302a996 ("vdpa: add vhost_vdpa_suspend")
Suggested-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Wafer Xie <wafer@jaguarmicro.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20251119132452.3117-1-wafer@jaguarmicro.com>
(cherry picked from commit fd3a2c601ab4a1bdb669e4c584b364e00a978702)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
parent
0b1ddf19d0
commit
ad2c2ef5e5
2 changed files with 9 additions and 5 deletions
|
|
@ -905,7 +905,7 @@ static int vhost_vdpa_reset_device(struct vhost_dev *dev)
|
||||||
|
|
||||||
memory_listener_unregister(&v->shared->listener);
|
memory_listener_unregister(&v->shared->listener);
|
||||||
v->shared->listener_registered = false;
|
v->shared->listener_registered = false;
|
||||||
v->suspended = false;
|
v->shared->suspended = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1354,7 +1354,7 @@ static void vhost_vdpa_suspend(struct vhost_dev *dev)
|
||||||
if (unlikely(r)) {
|
if (unlikely(r)) {
|
||||||
error_report("Cannot suspend: %s(%d)", g_strerror(errno), errno);
|
error_report("Cannot suspend: %s(%d)", g_strerror(errno), errno);
|
||||||
} else {
|
} else {
|
||||||
v->suspended = true;
|
v->shared->suspended = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1481,7 +1481,7 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v->suspended) {
|
if (!v->shared->suspended) {
|
||||||
/*
|
/*
|
||||||
* Cannot trust in value returned by device, let vhost recover used
|
* Cannot trust in value returned by device, let vhost recover used
|
||||||
* idx from guest.
|
* idx from guest.
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,12 @@ typedef struct vhost_vdpa_shared {
|
||||||
|
|
||||||
/* SVQ switching is in progress, or already completed? */
|
/* SVQ switching is in progress, or already completed? */
|
||||||
SVQTransitionState svq_switching;
|
SVQTransitionState svq_switching;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device suspended successfully.
|
||||||
|
* The vhost_vdpa devices cannot have different suspended states.
|
||||||
|
*/
|
||||||
|
bool suspended;
|
||||||
} VhostVDPAShared;
|
} VhostVDPAShared;
|
||||||
|
|
||||||
typedef struct vhost_vdpa {
|
typedef struct vhost_vdpa {
|
||||||
|
|
@ -83,8 +89,6 @@ typedef struct vhost_vdpa {
|
||||||
uint32_t address_space_id;
|
uint32_t address_space_id;
|
||||||
uint64_t acked_features;
|
uint64_t acked_features;
|
||||||
bool shadow_vqs_enabled;
|
bool shadow_vqs_enabled;
|
||||||
/* Device suspended successfully */
|
|
||||||
bool suspended;
|
|
||||||
VhostVDPAShared *shared;
|
VhostVDPAShared *shared;
|
||||||
GPtrArray *shadow_vqs;
|
GPtrArray *shadow_vqs;
|
||||||
const VhostShadowVirtqueueOps *shadow_vq_ops;
|
const VhostShadowVirtqueueOps *shadow_vq_ops;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue