mirror of https://github.com/proxmox/mirror_qemu
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>master
parent
f3034ad71f
commit
07536ddda7
|
@ -17,3 +17,17 @@ VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp)
|
||||||
{
|
{
|
||||||
return qmp_virtio_unsupported(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;
|
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 = {
|
static const TypeInfo virtio_device_info = {
|
||||||
.name = TYPE_VIRTIO_DEVICE,
|
.name = TYPE_VIRTIO_DEVICE,
|
||||||
.parent = TYPE_DEVICE,
|
.parent = TYPE_DEVICE,
|
||||||
|
|
256
qapi/virtio.json
256
qapi/virtio.json
|
@ -499,3 +499,259 @@
|
||||||
'data': { 'transports': [ 'str' ],
|
'data': { 'transports': [ 'str' ],
|
||||||
'*dev-features': [ 'str' ],
|
'*dev-features': [ 'str' ],
|
||||||
'*unknown-dev-features': 'uint64' } }
|
'*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