在 2022/8/16 09:06, Kangjie Xu 写道:
Introduce the interface vhost_reset_vring(). The interface is a wrapper
to send a VHOST_USER_RESET_VRING message to the back-end. It will reset
an individual vring in the back-end. Meanwhile, it will wait for a reply
to ensure the reset has been completed.
Signed-off-by: Kangjie Xu <kangjie...@linux.alibaba.com>
Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com>
---
hw/virtio/vhost-user.c | 41 +++++++++++++++++++++++++++++++
include/hw/virtio/vhost-backend.h | 3 +++
2 files changed, 44 insertions(+)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 75b8df21a4..56033f7a92 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -126,6 +126,7 @@ typedef enum VhostUserRequest {
VHOST_USER_GET_MAX_MEM_SLOTS = 36,
VHOST_USER_ADD_MEM_REG = 37,
VHOST_USER_REM_MEM_REG = 38,
+ VHOST_USER_RESET_VRING = 41,
VHOST_USER_MAX
} VhostUserRequest;
@@ -1498,6 +1499,45 @@ static int vhost_user_get_max_memslots(struct vhost_dev *dev,
return 0;
}
+static int vhost_user_reset_vring(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ int ret;
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_RESET_VRING,
+ .hdr.flags = VHOST_USER_VERSION,
Do we need VHOST_USER_NEED_REPLY_MASK here?
Other looks good.
Thanks
+ .payload.state = *ring,
+ .hdr.size = sizeof(msg.payload.state),
+ };
+
+ if (!virtio_has_feature(dev->acked_features, VIRTIO_F_RING_RESET)) {
+ return -ENOTSUP;
+ }
+
+ ret = vhost_user_write(dev, &msg, NULL, 0);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = vhost_user_read(dev, &msg);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (msg.hdr.request != VHOST_USER_RESET_VRING) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ VHOST_USER_RESET_VRING, msg.hdr.request);
+ return -EPROTO;
+ }
+
+ if (msg.hdr.size != sizeof(msg.payload.state)) {
+ error_report("Received bad msg size.");
+ return -EPROTO;
+ }
+
+ return 0;
+}
+
static int vhost_user_reset_device(struct vhost_dev *dev)
{
VhostUserMsg msg = {
@@ -2625,6 +2665,7 @@ const VhostOps user_ops = {
.vhost_set_features = vhost_user_set_features,
.vhost_get_features = vhost_user_get_features,
.vhost_set_owner = vhost_user_set_owner,
+ .vhost_reset_vring = vhost_user_reset_vring,
.vhost_reset_device = vhost_user_reset_device,
.vhost_get_vq_index = vhost_user_get_vq_index,
.vhost_set_vring_enable = vhost_user_set_vring_enable,
diff --git a/include/hw/virtio/vhost-backend.h
b/include/hw/virtio/vhost-backend.h
index eab46d7f0b..f23bf71a8d 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -79,6 +79,8 @@ typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
uint64_t *features);
typedef int (*vhost_set_backend_cap_op)(struct vhost_dev *dev);
typedef int (*vhost_set_owner_op)(struct vhost_dev *dev);
+typedef int (*vhost_reset_vring_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
@@ -154,6 +156,7 @@ typedef struct VhostOps {
vhost_set_backend_cap_op vhost_set_backend_cap;
vhost_set_owner_op vhost_set_owner;
vhost_reset_device_op vhost_reset_device;
+ vhost_reset_vring_op vhost_reset_vring;
vhost_get_vq_index_op vhost_get_vq_index;
vhost_set_vring_enable_op vhost_set_vring_enable;
vhost_requires_shm_log_op vhost_requires_shm_log;