mirror of https://gitee.com/openkylin/qemu.git
qmp: add QMP commands for virtio/vhost queue-status
These new commands show the internal status of a VirtIODevice's VirtQueue and a vhost device's vhost_virtqueue (if active). Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> Message-Id: <1660220684-24909-5-git-send-email-jonah.palmer@oracle.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
f3034ad71f
commit
07536ddda7
|
@ -17,3 +17,17 @@ VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
|
|||
{
|
||||
return qmp_virtio_unsupported(errp);
|
||||
}
|
||||
|
||||
VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path,
|
||||
uint16_t queue,
|
||||
Error **errp)
|
||||
{
|
||||
return qmp_virtio_unsupported(errp);
|
||||
}
|
||||
|
||||
VirtQueueStatus *qmp_x_query_virtio_queue_status(const char *path,
|
||||
uint16_t queue,
|
||||
Error **errp)
|
||||
{
|
||||
return qmp_virtio_unsupported(errp);
|
||||
}
|
||||
|
|
|
@ -4679,6 +4679,109 @@ VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
|
|||
return status;
|
||||
}
|
||||
|
||||
VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path,
|
||||
uint16_t queue,
|
||||
Error **errp)
|
||||
{
|
||||
VirtIODevice *vdev;
|
||||
VirtVhostQueueStatus *status;
|
||||
|
||||
vdev = virtio_device_find(path);
|
||||
if (vdev == NULL) {
|
||||
error_setg(errp, "Path %s is not a VirtIODevice", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!vdev->vhost_started) {
|
||||
error_setg(errp, "Error: vhost device has not started yet");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
struct vhost_dev *hdev = vdc->get_vhost(vdev);
|
||||
|
||||
if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) {
|
||||
error_setg(errp, "Invalid vhost virtqueue number %d", queue);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = g_new0(VirtVhostQueueStatus, 1);
|
||||
status->name = g_strdup(vdev->name);
|
||||
status->kick = hdev->vqs[queue].kick;
|
||||
status->call = hdev->vqs[queue].call;
|
||||
status->desc = (uintptr_t)hdev->vqs[queue].desc;
|
||||
status->avail = (uintptr_t)hdev->vqs[queue].avail;
|
||||
status->used = (uintptr_t)hdev->vqs[queue].used;
|
||||
status->num = hdev->vqs[queue].num;
|
||||
status->desc_phys = hdev->vqs[queue].desc_phys;
|
||||
status->desc_size = hdev->vqs[queue].desc_size;
|
||||
status->avail_phys = hdev->vqs[queue].avail_phys;
|
||||
status->avail_size = hdev->vqs[queue].avail_size;
|
||||
status->used_phys = hdev->vqs[queue].used_phys;
|
||||
status->used_size = hdev->vqs[queue].used_size;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
VirtQueueStatus *qmp_x_query_virtio_queue_status(const char *path,
|
||||
uint16_t queue,
|
||||
Error **errp)
|
||||
{
|
||||
VirtIODevice *vdev;
|
||||
VirtQueueStatus *status;
|
||||
|
||||
vdev = virtio_device_find(path);
|
||||
if (vdev == NULL) {
|
||||
error_setg(errp, "Path %s is not a VirtIODevice", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (queue >= VIRTIO_QUEUE_MAX || !virtio_queue_get_num(vdev, queue)) {
|
||||
error_setg(errp, "Invalid virtqueue number %d", queue);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = g_new0(VirtQueueStatus, 1);
|
||||
status->name = g_strdup(vdev->name);
|
||||
status->queue_index = vdev->vq[queue].queue_index;
|
||||
status->inuse = vdev->vq[queue].inuse;
|
||||
status->vring_num = vdev->vq[queue].vring.num;
|
||||
status->vring_num_default = vdev->vq[queue].vring.num_default;
|
||||
status->vring_align = vdev->vq[queue].vring.align;
|
||||
status->vring_desc = vdev->vq[queue].vring.desc;
|
||||
status->vring_avail = vdev->vq[queue].vring.avail;
|
||||
status->vring_used = vdev->vq[queue].vring.used;
|
||||
status->used_idx = vdev->vq[queue].used_idx;
|
||||
status->signalled_used = vdev->vq[queue].signalled_used;
|
||||
status->signalled_used_valid = vdev->vq[queue].signalled_used_valid;
|
||||
|
||||
if (vdev->vhost_started) {
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
struct vhost_dev *hdev = vdc->get_vhost(vdev);
|
||||
|
||||
/* check if vq index exists for vhost as well */
|
||||
if (queue >= hdev->vq_index && queue < hdev->vq_index + hdev->nvqs) {
|
||||
status->has_last_avail_idx = true;
|
||||
|
||||
int vhost_vq_index =
|
||||
hdev->vhost_ops->vhost_get_vq_index(hdev, queue);
|
||||
struct vhost_vring_state state = {
|
||||
.index = vhost_vq_index,
|
||||
};
|
||||
|
||||
status->last_avail_idx =
|
||||
hdev->vhost_ops->vhost_get_vring_base(hdev, &state);
|
||||
}
|
||||
} else {
|
||||
status->has_shadow_avail_idx = true;
|
||||
status->has_last_avail_idx = true;
|
||||
status->last_avail_idx = vdev->vq[queue].last_avail_idx;
|
||||
status->shadow_avail_idx = vdev->vq[queue].shadow_avail_idx;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_device_info = {
|
||||
.name = TYPE_VIRTIO_DEVICE,
|
||||
.parent = TYPE_DEVICE,
|
||||
|
|
256
qapi/virtio.json
256
qapi/virtio.json
|
@ -499,3 +499,259 @@
|
|||
'data': { 'transports': [ 'str' ],
|
||||
'*dev-features': [ 'str' ],
|
||||
'*unknown-dev-features': 'uint64' } }
|
||||
|
||||
##
|
||||
# @VirtQueueStatus:
|
||||
#
|
||||
# Information of a VirtIODevice VirtQueue, including most members of
|
||||
# the VirtQueue data structure.
|
||||
#
|
||||
# @name: Name of the VirtIODevice that uses this VirtQueue
|
||||
#
|
||||
# @queue-index: VirtQueue queue_index
|
||||
#
|
||||
# @inuse: VirtQueue inuse
|
||||
#
|
||||
# @vring-num: VirtQueue vring.num
|
||||
#
|
||||
# @vring-num-default: VirtQueue vring.num_default
|
||||
#
|
||||
# @vring-align: VirtQueue vring.align
|
||||
#
|
||||
# @vring-desc: VirtQueue vring.desc (descriptor area)
|
||||
#
|
||||
# @vring-avail: VirtQueue vring.avail (driver area)
|
||||
#
|
||||
# @vring-used: VirtQueue vring.used (device area)
|
||||
#
|
||||
# @last-avail-idx: VirtQueue last_avail_idx or return of vhost_dev
|
||||
# vhost_get_vring_base (if vhost active)
|
||||
#
|
||||
# @shadow-avail-idx: VirtQueue shadow_avail_idx
|
||||
#
|
||||
# @used-idx: VirtQueue used_idx
|
||||
#
|
||||
# @signalled-used: VirtQueue signalled_used
|
||||
#
|
||||
# @signalled-used-valid: VirtQueue signalled_used_valid flag
|
||||
#
|
||||
# Since: 7.1
|
||||
#
|
||||
##
|
||||
|
||||
{ 'struct': 'VirtQueueStatus',
|
||||
'data': { 'name': 'str',
|
||||
'queue-index': 'uint16',
|
||||
'inuse': 'uint32',
|
||||
'vring-num': 'uint32',
|
||||
'vring-num-default': 'uint32',
|
||||
'vring-align': 'uint32',
|
||||
'vring-desc': 'uint64',
|
||||
'vring-avail': 'uint64',
|
||||
'vring-used': 'uint64',
|
||||
'*last-avail-idx': 'uint16',
|
||||
'*shadow-avail-idx': 'uint16',
|
||||
'used-idx': 'uint16',
|
||||
'signalled-used': 'uint16',
|
||||
'signalled-used-valid': 'bool' } }
|
||||
|
||||
##
|
||||
# @x-query-virtio-queue-status:
|
||||
#
|
||||
# Return the status of a given VirtIODevice's VirtQueue
|
||||
#
|
||||
# @path: VirtIODevice canonical QOM path
|
||||
#
|
||||
# @queue: VirtQueue index to examine
|
||||
#
|
||||
# Features:
|
||||
# @unstable: This command is meant for debugging.
|
||||
#
|
||||
# Returns: VirtQueueStatus of the VirtQueue
|
||||
#
|
||||
# Notes: last_avail_idx will not be displayed in the case where
|
||||
# the selected VirtIODevice has a running vhost device and
|
||||
# the VirtIODevice VirtQueue index (queue) does not exist for
|
||||
# the corresponding vhost device vhost_virtqueue. Also,
|
||||
# shadow_avail_idx will not be displayed in the case where
|
||||
# the selected VirtIODevice has a running vhost device.
|
||||
#
|
||||
# Since: 7.1
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# 1. Get VirtQueueStatus for virtio-vsock (vhost-vsock running)
|
||||
#
|
||||
# -> { "execute": "x-query-virtio-queue-status",
|
||||
# "arguments": { "path": "/machine/peripheral/vsock0/virtio-backend",
|
||||
# "queue": 1 }
|
||||
# }
|
||||
# <- { "return": {
|
||||
# "signalled-used": 0,
|
||||
# "inuse": 0,
|
||||
# "name": "vhost-vsock",
|
||||
# "vring-align": 4096,
|
||||
# "vring-desc": 5217370112,
|
||||
# "signalled-used-valid": false,
|
||||
# "vring-num-default": 128,
|
||||
# "vring-avail": 5217372160,
|
||||
# "queue-index": 1,
|
||||
# "last-avail-idx": 0,
|
||||
# "vring-used": 5217372480,
|
||||
# "used-idx": 0,
|
||||
# "vring-num": 128
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# 2. Get VirtQueueStatus for virtio-serial (no vhost)
|
||||
#
|
||||
# -> { "execute": "x-query-virtio-queue-status",
|
||||
# "arguments": { "path": "/machine/peripheral-anon/device[0]/virtio-backend",
|
||||
# "queue": 20 }
|
||||
# }
|
||||
# <- { "return": {
|
||||
# "signalled-used": 0,
|
||||
# "inuse": 0,
|
||||
# "name": "virtio-serial",
|
||||
# "vring-align": 4096,
|
||||
# "vring-desc": 5182074880,
|
||||
# "signalled-used-valid": false,
|
||||
# "vring-num-default": 128,
|
||||
# "vring-avail": 5182076928,
|
||||
# "queue-index": 20,
|
||||
# "last-avail-idx": 0,
|
||||
# "vring-used": 5182077248,
|
||||
# "used-idx": 0,
|
||||
# "shadow-avail-idx": 0,
|
||||
# "vring-num": 128
|
||||
# }
|
||||
# }
|
||||
#
|
||||
##
|
||||
|
||||
{ 'command': 'x-query-virtio-queue-status',
|
||||
'data': { 'path': 'str', 'queue': 'uint16' },
|
||||
'returns': 'VirtQueueStatus',
|
||||
'features': [ 'unstable' ] }
|
||||
|
||||
##
|
||||
# @VirtVhostQueueStatus:
|
||||
#
|
||||
# Information of a vhost device's vhost_virtqueue, including most
|
||||
# members of the vhost_dev vhost_virtqueue data structure.
|
||||
#
|
||||
# @name: Name of the VirtIODevice that uses this vhost_virtqueue
|
||||
#
|
||||
# @kick: vhost_virtqueue kick
|
||||
#
|
||||
# @call: vhost_virtqueue call
|
||||
#
|
||||
# @desc: vhost_virtqueue desc
|
||||
#
|
||||
# @avail: vhost_virtqueue avail
|
||||
#
|
||||
# @used: vhost_virtqueue used
|
||||
#
|
||||
# @num: vhost_virtqueue num
|
||||
#
|
||||
# @desc-phys: vhost_virtqueue desc_phys (descriptor area phys. addr.)
|
||||
#
|
||||
# @desc-size: vhost_virtqueue desc_size
|
||||
#
|
||||
# @avail-phys: vhost_virtqueue avail_phys (driver area phys. addr.)
|
||||
#
|
||||
# @avail-size: vhost_virtqueue avail_size
|
||||
#
|
||||
# @used-phys: vhost_virtqueue used_phys (device area phys. addr.)
|
||||
#
|
||||
# @used-size: vhost_virtqueue used_size
|
||||
#
|
||||
# Since: 7.1
|
||||
#
|
||||
##
|
||||
|
||||
{ 'struct': 'VirtVhostQueueStatus',
|
||||
'data': { 'name': 'str',
|
||||
'kick': 'int',
|
||||
'call': 'int',
|
||||
'desc': 'uint64',
|
||||
'avail': 'uint64',
|
||||
'used': 'uint64',
|
||||
'num': 'int',
|
||||
'desc-phys': 'uint64',
|
||||
'desc-size': 'uint32',
|
||||
'avail-phys': 'uint64',
|
||||
'avail-size': 'uint32',
|
||||
'used-phys': 'uint64',
|
||||
'used-size': 'uint32' } }
|
||||
|
||||
##
|
||||
# @x-query-virtio-vhost-queue-status:
|
||||
#
|
||||
# Return information of a given vhost device's vhost_virtqueue
|
||||
#
|
||||
# @path: VirtIODevice canonical QOM path
|
||||
#
|
||||
# @queue: vhost_virtqueue index to examine
|
||||
#
|
||||
# Features:
|
||||
# @unstable: This command is meant for debugging.
|
||||
#
|
||||
# Returns: VirtVhostQueueStatus of the vhost_virtqueue
|
||||
#
|
||||
# Since: 7.1
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# 1. Get vhost_virtqueue status for vhost-crypto
|
||||
#
|
||||
# -> { "execute": "x-query-virtio-vhost-queue-status",
|
||||
# "arguments": { "path": "/machine/peripheral/crypto0/virtio-backend",
|
||||
# "queue": 0 }
|
||||
# }
|
||||
# <- { "return": {
|
||||
# "avail-phys": 5216124928,
|
||||
# "name": "virtio-crypto",
|
||||
# "used-phys": 5216127040,
|
||||
# "avail-size": 2054,
|
||||
# "desc-size": 16384,
|
||||
# "used-size": 8198,
|
||||
# "desc": 140141447430144,
|
||||
# "num": 1024,
|
||||
# "call": 0,
|
||||
# "avail": 140141447446528,
|
||||
# "desc-phys": 5216108544,
|
||||
# "used": 140141447448640,
|
||||
# "kick": 0
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# 2. Get vhost_virtqueue status for vhost-vsock
|
||||
#
|
||||
# -> { "execute": "x-query-virtio-vhost-queue-status",
|
||||
# "arguments": { "path": "/machine/peripheral/vsock0/virtio-backend",
|
||||
# "queue": 0 }
|
||||
# }
|
||||
# <- { "return": {
|
||||
# "avail-phys": 5182261248,
|
||||
# "name": "vhost-vsock",
|
||||
# "used-phys": 5182261568,
|
||||
# "avail-size": 262,
|
||||
# "desc-size": 2048,
|
||||
# "used-size": 1030,
|
||||
# "desc": 140141413580800,
|
||||
# "num": 128,
|
||||
# "call": 0,
|
||||
# "avail": 140141413582848,
|
||||
# "desc-phys": 5182259200,
|
||||
# "used": 140141413583168,
|
||||
# "kick": 0
|
||||
# }
|
||||
# }
|
||||
#
|
||||
##
|
||||
|
||||
{ 'command': 'x-query-virtio-vhost-queue-status',
|
||||
'data': { 'path': 'str', 'queue': 'uint16' },
|
||||
'returns': 'VirtVhostQueueStatus',
|
||||
'features': [ 'unstable' ] }
|
||||
|
|
Loading…
Reference in New Issue