From: Laurent Vivier <lvivier@redhat.com>
This patch implements HMP version of the virtio QMP commands
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com>
---
docs/system/monitor.rst | 2 +
hmp-commands-virtio.hx | 162 ++++++++++++++++++++++++++++++++++++++
hmp-commands.hx | 10 +++
hw/virtio/virtio.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++-
include/monitor/hmp.h | 4 +
meson.build | 1 +
monitor/misc.c | 17 ++++
7 files changed, 399 insertions(+), 1 deletion(-)
create mode 100644 hmp-commands-virtio.hx
[Jonah: Added relative indicies, device type, and used index
in HMP virtio queue-status command.]
diff --git a/docs/system/monitor.rst b/docs/system/monitor.rst
index ff5c434..10418fc 100644
--- a/docs/system/monitor.rst
+++ b/docs/system/monitor.rst
@@ -21,6 +21,8 @@ The following commands are available:
.. hxtool-doc:: hmp-commands.hx
+.. hxtool-doc:: hmp-commands-virtio.hx
+
.. hxtool-doc:: hmp-commands-info.hx
Integer expressions
diff --git a/hmp-commands-virtio.hx b/hmp-commands-virtio.hx
new file mode 100644
index 0000000..0ef01b9
--- /dev/null
+++ b/hmp-commands-virtio.hx
@@ -0,0 +1,162 @@
+HXCOMM Use DEFHEADING() to define headings in both help text and rST.
+HXCOMM Text between SRST and ERST is copied to the rST version and
+HXCOMM discarded from C version.
+HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
+HXCOMM monitor info commands
+HXCOMM HXCOMM can be used for comments, discarded from both rST and C.
+HXCOMM
+HXCOMM In this file, generally SRST fragments should have two extra
+HXCOMM spaces of indent, so that the documentation list item for "virtio cmd"
+HXCOMM appears inside the documentation list item for the top level
+HXCOMM "virtio" documentation entry. The exception is the first SRST
+HXCOMM fragment that defines that top level entry.
+
+SRST
+``virtio`` *subcommand*
+ Show various information about virtio.
+
+ Example:
+
+ List all sub-commands::
+
+ (qemu) virtio
+ virtio query -- List all available virtio devices
+ virtio status path -- Display status of a given virtio device
+ virtio queue-status path queue -- Display status of a given virtio queue
+ virtio queue-element path queue [index] -- Display element of a given virtio queue
+
+ERST
+
+ {
+ .name = "query",
+ .args_type = "",
+ .params = "",
+ .help = "List all available virtio devices",
+ .cmd = hmp_virtio_query,
+ .flags = "p",
+ },
+
+SRST
+ ``virtio query``
+ List all available virtio devices
+
+ Example:
+
+ List all available virtio devices in the machine::
+
+ (qemu) virtio query
+ /machine/peripheral-anon/device[3]/virtio-backend [virtio-net]
+ /machine/peripheral-anon/device[1]/virtio-backend [virtio-serial]
+ /machine/peripheral-anon/device[0]/virtio-backend [virtio-blk]
+
+ERST
+
+ {
+ .name = "status",
+ .args_type = "path:s",
+ .params = "path",
+ .help = "Display status of a given virtio device",
+ .cmd = hmp_virtio_status,
+ .flags = "p",
+ },
+
+SRST
+ ``virtio status`` *path*
+ Display status of a given virtio device
+
+ Example:
+
+ Dump the status of the first virtio device::
+
+ (qemu) virtio status /machine/peripheral-anon/device[3]/virtio-backend
+ /machine/peripheral-anon/device[3]/virtio-backend:
+ Device Id: 1
+ Guest features: event-idx, indirect-desc, version-1
+ ctrl-mac-addr, guest-announce, ctrl-vlan, ctrl-rx, ctrl-vq, status, mrg-rxbuf, host-ufo, host-ecn, host-tso6, host-tso4, guest-ufo, guest-ecn, guest-tso6, guest-tso4, mac, ctrl-guest-offloads, guest-csum, csum
+ Host features: event-idx, indirect-desc, bad-feature, version-1, any-layout, notify-on-empty
+ gso, ctrl-mac-addr, guest-announce, ctrl-rx-extra, ctrl-vlan, ctrl-rx, ctrl-vq, status, mrg-rxbuf, host-ufo, host-ecn, host-tso6, host-tso4, guest-ufo, guest-ecn, guest-tso6, guest-tso4, mac, ctrl-guest-offloads, guest-csum, csum
+ Backend features:
+ Endianness: little
+ VirtQueues: 3
+
+ERST
+
+ {
+ .name = "queue-status",
+ .args_type = "path:s,queue:i",
+ .params = "path queue",
+ .help = "Display status of a given virtio queue",
+ .cmd = hmp_virtio_queue_status,
+ .flags = "p",
+ },
+
+SRST
+ ``virtio queue-status`` *path* *queue*
+ Display status of a given virtio queue
+
+ Example:
+
+ Dump the status of the first queue of the first virtio device::
+
+ (qemu) virtio queue-status /machine/peripheral-anon/device[3]/virtio-backend 0
+ /machine/peripheral-anon/device[3]/virtio-backend:
+ device_type: virtio-net
+ index: 0
+ inuse: 0
+ last_avail_idx: 61 (61 % 256)
+ shadow_avail_idx: 292 (36 % 256)
+ used_idx: 61 (61 % 256)
+ signalled_used: 61 (61 % 256)
+ signalled_used_valid: 1
+ VRing:
+ num: 256
+ num_default: 256
+ align: 4096
+ desc: 0x000000006c352000
+ avail: 0x000000006c353000
+ used: 0x000000006c353240
+
+ERST
+
+ {
+ .name = "queue-element",
+ .args_type = "path:s,queue:i,index:i?",
+ .params = "path queue [index]",
+ .help = "Display element of a given virtio queue",
+ .cmd = hmp_virtio_queue_element,
+ .flags = "p",
+ },
+
+SRST
+ ``virtio queue-element`` *path* *queue* [*index*]
+ Display element of a given virtio queue
+
+ Example:
+
+ Dump the information of the head element of the first queue of
+ the first virtio device::
+
+ (qemu) virtio queue-element/machine/peripheral-anon/device[3]/virtio-backend 0
+ index: 67
+ ndescs: 1
+ descs: addr 0x6fe69800 len 1536 (write)
+
+ (qemu) xp/128bx 0x6fe69800
+ 000000006fe69800: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+ 000000006fe69808: 0x00 0x00 0x01 0x00 0x52 0x54 0x00 0x12
+ 000000006fe69810: 0x34 0x56 0x52 0x54 0x00 0x09 0x51 0xde
+ 000000006fe69818: 0x08 0x00 0x45 0x00 0x00 0x4c 0x8f 0x32
+
+ device[3] is a virtio-net device and we can see in the element buffer the
+ MAC address of the card::
+
+ [root@localhost ~]# ip link show ens4
+ 2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP m0
+ link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
+
+ and the MAC address of the gateway::
+
+ [root@localhost ~]# arp -a
+ _gateway (192.168.122.1) at 52:54:00:09:51:de [ether] on ens4
+
+ERST
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8e45bce..4ef0630 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1720,6 +1720,16 @@ SRST
ERST
{
+ .name = "virtio",
+ .args_type = "name:S?",
+ .params = "[cmd]",
+ .help = "show various information about virtio",
+ .cmd = hmp_virtio_help,
+ .sub_table = hmp_virtio_cmds,
+ .flags = "p",
+ },
+
+ {
.name = "info",
.args_type = "item:s?",
.params = "[subcommand]",
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index bd4d13d..db0c5b8 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -31,6 +31,9 @@
#include "sysemu/runstate.h"
#include "standard-headers/linux/virtio_ids.h"
#include CONFIG_DEVICES
+#include "monitor/hmp.h"
+#include "monitor/monitor.h"
+#include "qapi/qmp/qdict.h"
static QTAILQ_HEAD(, VirtIODevice) virtio_list;
@@ -3919,6 +3922,32 @@ VirtioInfoList *qmp_x_debug_query_virtio(Error **errp)
return list;
}
+void hmp_virtio_query(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ VirtioInfoList *list = qmp_x_debug_query_virtio(&err);
+ VirtioInfoList *node;
+
+ if (err != NULL) {
+ hmp_handle_error(mon, err);
+ return;
+ }
+
+ if (list == NULL) {
+ monitor_printf(mon, "No VirtIO devices\n");
+ return;
+ }
+
+ node = list;
+ while (node) {
+ monitor_printf(mon, "%s [%s]\n", node->value->path,
+ VirtioType_str(node->value->type));
+ node = node->next;
+ }
+
+ qapi_free_VirtioInfoList(list);
+}
+
static VirtIODevice *virtio_device_find(const char *path)
{
VirtIODevice *vdev;
@@ -3972,8 +4001,48 @@ VirtQueueStatus *qmp_x_debug_virtio_queue_status(const char *path,
return status;
}
+void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ const char *path = qdict_get_try_str(qdict, "path");
+ int queue = qdict_get_int(qdict, "queue");
+ VirtQueueStatus *s = qmp_x_debug_virtio_queue_status(path, queue, &err);
+
+ if (err != NULL) {
+ hmp_handle_error(mon, err);
+ return;
+ }
+
+ monitor_printf(mon, "%s:\n", path);
+ monitor_printf(mon, " device_type: %s\n",
+ VirtioType_str(s->device_type));
+ monitor_printf(mon, " index: %d\n", s->queue_index);
+ monitor_printf(mon, " inuse: %d\n", s->inuse);
+ monitor_printf(mon, " last_avail_idx: %d (%"PRId64" %% %"PRId64")\n",
+ s->last_avail_idx, s->last_avail_idx % s->vring_num,
+ s->vring_num);
+ monitor_printf(mon, " shadow_avail_idx: %d (%"PRId64" %% %"PRId64")\n",
+ s->shadow_avail_idx, s->shadow_avail_idx % s->vring_num,
+ s->vring_num);
+ monitor_printf(mon, " used_idx: %d (%"PRId64" %% %"PRId64")\n",
+ s->used_idx, s->used_idx % s->vring_num, s->vring_num);
+ monitor_printf(mon, " signalled_used: %d (%"PRId64" %% %"PRId64")\n",
+ s->signalled_used, s->signalled_used % s->vring_num,
+ s->vring_num);
+ monitor_printf(mon, " signalled_used_valid: %d\n", s->signalled_used_valid);
+ monitor_printf(mon, " VRing:\n");
+ monitor_printf(mon, " num: %"PRId64"\n", s->vring_num);
+ monitor_printf(mon, " num_default: %"PRId64"\n", s->vring_num_default);
+ monitor_printf(mon, " align: %"PRId64"\n", s->vring_align);
+ monitor_printf(mon, " desc: 0x%016"PRIx64"\n", s->vring_desc);
+ monitor_printf(mon, " avail: 0x%016"PRIx64"\n", s->vring_avail);
+ monitor_printf(mon, " used: 0x%016"PRIx64"\n", s->vring_used);
+
+ qapi_free_VirtQueueStatus(s);
+}
+
#define CONVERT_FEATURES(type, map) \
- ({ \
+ ({ \
type *list = NULL; \
type *node; \
for (i = 0; map[i].virtio_bit != -1; i++) {\
@@ -4106,6 +4175,93 @@ VirtioStatus *qmp_x_debug_virtio_status(const char* path, Error **errp)
return status;
}
+#define DUMP_FEATURES(type, field) \
+ do { \
+ type##FeatureList * list = features->u.field.features; \
+ if (list) { \
+ monitor_printf(mon, " "); \
+ while (list) { \
+ monitor_printf(mon, "%s", type##Feature_str(list->value)); \
+ list = list->next; \
+ if (list != NULL) { \
+ monitor_printf(mon, ", "); \
+ } \
+ } \
+ monitor_printf(mon, "\n"); \
+ } \
+ } while (0)
+
+static void hmp_virtio_dump_features(Monitor *mon,
+ VirtioDeviceFeatures *features)
+{
+ VirtioTransportFeatureList *transport_list = features->transport;
+ while (transport_list) {
+ monitor_printf(mon, "%s",
+ VirtioTransportFeature_str(transport_list->value));
+ transport_list = transport_list->next;
+ if (transport_list != NULL) {
+ monitor_printf(mon, ", ");
+ }
+ }
+ monitor_printf(mon, "\n");
+ switch (features->type) {
+ case VIRTIO_TYPE_VIRTIO_SERIAL:
+ DUMP_FEATURES(VirtioSerial, virtio_serial);
+ break;
+ case VIRTIO_TYPE_VIRTIO_BLK:
+ DUMP_FEATURES(VirtioBlk, virtio_blk);
+ break;
+ case VIRTIO_TYPE_VIRTIO_GPU:
+ DUMP_FEATURES(VirtioGpu, virtio_gpu);
+ break;
+ case VIRTIO_TYPE_VIRTIO_NET:
+ DUMP_FEATURES(VirtioNet, virtio_net);
+ break;
+ case VIRTIO_TYPE_VIRTIO_SCSI:
+ DUMP_FEATURES(VirtioScsi, virtio_scsi);
+ break;
+ case VIRTIO_TYPE_VIRTIO_BALLOON:
+ DUMP_FEATURES(VirtioBalloon, virtio_balloon);
+ break;
+ case VIRTIO_TYPE_VIRTIO_IOMMU:
+ DUMP_FEATURES(VirtioIommu, virtio_iommu);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ if (features->has_unknown_features) {
+ monitor_printf(mon, " "
+ "unknown-features(0x%016"PRIx64")\n",
+ features->unknown_features);
+ }
+}
+
+void hmp_virtio_status(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ const char *path = qdict_get_try_str(qdict, "path");
+ VirtioStatus *s = qmp_x_debug_virtio_status(path, &err);
+
+ if (err != NULL) {
+ hmp_handle_error(mon, err);
+ return;
+ }
+
+ monitor_printf(mon, "%s:\n", path);
+ monitor_printf(mon, " Device Id: %"PRId64"\n", s->device_id);
+ monitor_printf(mon, " Guest features: ");
+ hmp_virtio_dump_features(mon, s->guest_features);
+ monitor_printf(mon, " Host features: ");
+ hmp_virtio_dump_features(mon, s->host_features);
+ monitor_printf(mon, " Backend features: ");
+ hmp_virtio_dump_features(mon, s->backend_features);
+ monitor_printf(mon, " Endianness: %s\n",
+ VirtioStatusEndianness_str(s->device_endian));
+ monitor_printf(mon, " VirtQueues: %d\n", s->num_vqs);
+
+ qapi_free_VirtioStatus(s);
+}
+
static VirtioRingDescFlagsList *qmp_decode_vring_desc_flags(uint16_t flags)
{
VirtioRingDescFlagsList *list = NULL;
@@ -4241,6 +4397,52 @@ done:
return element;
}
+void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ const char *path = qdict_get_try_str(qdict, "path");
+ int queue = qdict_get_int(qdict, "queue");
+ int index = qdict_get_try_int(qdict, "index", -1);
+ VirtioQueueElement *element;
+ VirtioRingDescList *list;
+
+ element = qmp_x_debug_virtio_queue_element(path, queue, index != -1,
+ index, &err);
+ if (err != NULL) {
+ hmp_handle_error(mon, err);
+ return;
+ }
+
+ monitor_printf(mon, "index: %d\n", element->index);
+ monitor_printf(mon, "ndescs: %d\n", element->ndescs);
+ monitor_printf(mon, "descs: ");
+
+ list = element->descs;
+ while (list) {
+ monitor_printf(mon, "addr 0x%"PRIx64" len %d", list->value->addr,
+ list->value->len);
+ if (list->value->flags) {
+ VirtioRingDescFlagsList *flag = list->value->flags;
+ monitor_printf(mon, " (");
+ while (flag) {
+ monitor_printf(mon, "%s", VirtioRingDescFlags_str(flag->value));
+ flag = flag->next;
+ if (flag) {
+ monitor_printf(mon, ", ");
+ }
+ }
+ monitor_printf(mon, ")");
+ }
+ list = list->next;
+ if (list) {
+ monitor_printf(mon, ", ");
+ }
+ }
+ monitor_printf(mon, "\n");
+
+ qapi_free_VirtioQueueElement(element);
+}
+
static const TypeInfo virtio_device_info = {
.name = TYPE_VIRTIO_DEVICE,
.parent = TYPE_DEVICE,
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 3baa105..e777b32 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -94,6 +94,10 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict);
void hmp_qom_get(Monitor *mon, const QDict *qdict);
void hmp_qom_set(Monitor *mon, const QDict *qdict);
void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
+void hmp_virtio_query(Monitor *mon, const QDict *qdict);
+void hmp_virtio_status(Monitor *mon, const QDict *qdict);
+void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict);
+void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict);
void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/meson.build b/meson.build
index eb362ee..d690de2 100644
--- a/meson.build
+++ b/meson.build
@@ -1964,6 +1964,7 @@ if have_system
hx_headers += [
['hmp-commands.hx', 'hmp-commands.h'],
['hmp-commands-info.hx', 'hmp-commands-info.h'],
+ ['hmp-commands-virtio.hx', 'hmp-commands-virtio.h'],
]
endif
foreach d : hx_headers
diff --git a/monitor/misc.c b/monitor/misc.c
index 1539e18..ef8f87c 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include CONFIG_DEVICES
#include "monitor-internal.h"
#include "monitor/qdev.h"
#include "hw/usb.h"
@@ -219,6 +220,15 @@ static void hmp_info_help(Monitor *mon, const QDict *qdict)
help_cmd(mon, "info");
}
+static void hmp_virtio_help(Monitor *mon, const QDict *qdict)
+{
+#if defined(CONFIG_VIRTIO)
+ help_cmd(mon, "virtio");
+#else
+ monitor_printf(mon, "Virtio is disabled\n");
+#endif
+}
+
static void monitor_init_qmp_commands(void)
{
/*
@@ -1451,6 +1461,13 @@ static HMPCommand hmp_info_cmds[] = {
{ NULL, NULL, },
};
+static HMPCommand hmp_virtio_cmds[] = {
+#if defined(CONFIG_VIRTIO)
+#include "hmp-commands-virtio.h"
+#endif
+ { NULL, NULL, },
+};
+
/* hmp_cmds and hmp_info_cmds would be sorted at runtime */
HMPCommand hmp_cmds[] = {
#include "hmp-commands.h"
--
1.8.3.1
在 2021/7/12 下午6:35, Jonah Palmer 写道:
> +void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
> +{
> + Error *err = NULL;
> + const char *path = qdict_get_try_str(qdict, "path");
> + int queue = qdict_get_int(qdict, "queue");
> + VirtQueueStatus *s = qmp_x_debug_virtio_queue_status(path, queue, &err);
> +
> + if (err != NULL) {
> + hmp_handle_error(mon, err);
> + return;
> + }
> +
> + monitor_printf(mon, "%s:\n", path);
> + monitor_printf(mon, " device_type: %s\n",
> + VirtioType_str(s->device_type));
> + monitor_printf(mon, " index: %d\n", s->queue_index);
> + monitor_printf(mon, " inuse: %d\n", s->inuse);
> + monitor_printf(mon, " last_avail_idx: %d (%"PRId64" %% %"PRId64")\n",
> + s->last_avail_idx, s->last_avail_idx % s->vring_num,
> + s->vring_num);
> + monitor_printf(mon, " shadow_avail_idx: %d (%"PRId64" %% %"PRId64")\n",
> + s->shadow_avail_idx, s->shadow_avail_idx % s->vring_num,
> + s->vring_num);
> + monitor_printf(mon, " used_idx: %d (%"PRId64" %% %"PRId64")\n",
> + s->used_idx, s->used_idx % s->vring_num, s->vring_num);
The modular information is not the case of packed ring where the queue
size does not have to be a power of 2.
Thanks
> + monitor_printf(mon, " signalled_used: %d (%"PRId64" %% %"PRId64")\n",
> + s->signalled_used, s->signalled_used % s->vring_num,
> + s->vring_num);
> + monitor_printf(mon, " signalled_used_valid: %d\n", s->signalled_used_valid);
> + monitor_printf(mon, " VRing:\n");
> + monitor_printf(mon, " num: %"PRId64"\n", s->vring_num);
> + monitor_printf(mon, " num_default: %"PRId64"\n", s->vring_num_default);
> + monitor_printf(mon, " align: %"PRId64"\n", s->vring_align);
> + monitor_printf(mon, " desc: 0x%016"PRIx64"\n", s->vring_desc);
> + monitor_printf(mon, " avail: 0x%016"PRIx64"\n", s->vring_avail);
> + monitor_printf(mon, " used: 0x%016"PRIx64"\n", s->vring_used);
> +
> + qapi_free_VirtQueueStatus(s);
On 7/13/21 10:40 PM, Jason Wang wrote:
>
> 在 2021/7/12 下午6:35, Jonah Palmer 写道:
>> +void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
>> +{
>> + Error *err = NULL;
>> + const char *path = qdict_get_try_str(qdict, "path");
>> + int queue = qdict_get_int(qdict, "queue");
>> + VirtQueueStatus *s = qmp_x_debug_virtio_queue_status(path,
>> queue, &err);
>> +
>> + if (err != NULL) {
>> + hmp_handle_error(mon, err);
>> + return;
>> + }
>> +
>> + monitor_printf(mon, "%s:\n", path);
>> + monitor_printf(mon, " device_type: %s\n",
>> + VirtioType_str(s->device_type));
>> + monitor_printf(mon, " index: %d\n",
>> s->queue_index);
>> + monitor_printf(mon, " inuse: %d\n", s->inuse);
>> + monitor_printf(mon, " last_avail_idx: %d (%"PRId64" %%
>> %"PRId64")\n",
>> + s->last_avail_idx, s->last_avail_idx % s->vring_num,
>> + s->vring_num);
>> + monitor_printf(mon, " shadow_avail_idx: %d (%"PRId64" %%
>> %"PRId64")\n",
>> + s->shadow_avail_idx, s->shadow_avail_idx %
>> s->vring_num,
>> + s->vring_num);
>> + monitor_printf(mon, " used_idx: %d (%"PRId64" %%
>> %"PRId64")\n",
>> + s->used_idx, s->used_idx % s->vring_num,
>> s->vring_num);
>
>
> The modular information is not the case of packed ring where the queue
> size does not have to be a power of 2.
Doesn't modulo work for any integer, regardless if it's a power of 2 or not? Could you clarify this for me?
Thank you,
Jonah
>
> Thanks
>
>
>> + monitor_printf(mon, " signalled_used: %d (%"PRId64" %%
>> %"PRId64")\n",
>> + s->signalled_used, s->signalled_used % s->vring_num,
>> + s->vring_num);
>> + monitor_printf(mon, " signalled_used_valid: %d\n",
>> s->signalled_used_valid);
>> + monitor_printf(mon, " VRing:\n");
>> + monitor_printf(mon, " num: %"PRId64"\n", s->vring_num);
>> + monitor_printf(mon, " num_default: %"PRId64"\n",
>> s->vring_num_default);
>> + monitor_printf(mon, " align: %"PRId64"\n",
>> s->vring_align);
>> + monitor_printf(mon, " desc: 0x%016"PRIx64"\n",
>> s->vring_desc);
>> + monitor_printf(mon, " avail: 0x%016"PRIx64"\n",
>> s->vring_avail);
>> + monitor_printf(mon, " used: 0x%016"PRIx64"\n",
>> s->vring_used);
>> +
>> + qapi_free_VirtQueueStatus(s);
>
在 2021/7/21 下午5:11, Jonah Palmer 写道:
>
>
> On 7/13/21 10:40 PM, Jason Wang wrote:
>>
>> 在 2021/7/12 下午6:35, Jonah Palmer 写道:
>>> +void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
>>> +{
>>> + Error *err = NULL;
>>> + const char *path = qdict_get_try_str(qdict, "path");
>>> + int queue = qdict_get_int(qdict, "queue");
>>> + VirtQueueStatus *s = qmp_x_debug_virtio_queue_status(path,
>>> queue, &err);
>>> +
>>> + if (err != NULL) {
>>> + hmp_handle_error(mon, err);
>>> + return;
>>> + }
>>> +
>>> + monitor_printf(mon, "%s:\n", path);
>>> + monitor_printf(mon, " device_type: %s\n",
>>> + VirtioType_str(s->device_type));
>>> + monitor_printf(mon, " index: %d\n",
>>> s->queue_index);
>>> + monitor_printf(mon, " inuse: %d\n", s->inuse);
>>> + monitor_printf(mon, " last_avail_idx: %d (%"PRId64" %%
>>> %"PRId64")\n",
>>> + s->last_avail_idx, s->last_avail_idx %
>>> s->vring_num,
>>> + s->vring_num);
>>> + monitor_printf(mon, " shadow_avail_idx: %d (%"PRId64" %%
>>> %"PRId64")\n",
>>> + s->shadow_avail_idx, s->shadow_avail_idx %
>>> s->vring_num,
>>> + s->vring_num);
>>> + monitor_printf(mon, " used_idx: %d (%"PRId64" %%
>>> %"PRId64")\n",
>>> + s->used_idx, s->used_idx % s->vring_num,
>>> s->vring_num);
>>
>>
>> The modular information is not the case of packed ring where the
>> queue size does not have to be a power of 2.
> Doesn't modulo work for any integer, regardless if it's a power of 2 or not? Could you clarify this for me?
For packed ring, the index doesn't increase freely, it's always small
than the virtqueue size.
So showing the modulo arithmetic seems useless since the device or
driver doesn't use modulo for calculating the real offset.
Thanks
>
> Thank you,
On 7/22/21 5:18 AM, Jason Wang wrote:
>
> 在 2021/7/21 下午5:11, Jonah Palmer 写道:
>>
>>
>> On 7/13/21 10:40 PM, Jason Wang wrote:
>>>
>>> 在 2021/7/12 下午6:35, Jonah Palmer 写道:
>>>> +void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
>>>> +{
>>>> + Error *err = NULL;
>>>> + const char *path = qdict_get_try_str(qdict, "path");
>>>> + int queue = qdict_get_int(qdict, "queue");
>>>> + VirtQueueStatus *s = qmp_x_debug_virtio_queue_status(path,
>>>> queue, &err);
>>>> +
>>>> + if (err != NULL) {
>>>> + hmp_handle_error(mon, err);
>>>> + return;
>>>> + }
>>>> +
>>>> + monitor_printf(mon, "%s:\n", path);
>>>> + monitor_printf(mon, " device_type: %s\n",
>>>> + VirtioType_str(s->device_type));
>>>> + monitor_printf(mon, " index: %d\n",
>>>> s->queue_index);
>>>> + monitor_printf(mon, " inuse: %d\n", s->inuse);
>>>> + monitor_printf(mon, " last_avail_idx: %d (%"PRId64" %%
>>>> %"PRId64")\n",
>>>> + s->last_avail_idx, s->last_avail_idx %
>>>> s->vring_num,
>>>> + s->vring_num);
>>>> + monitor_printf(mon, " shadow_avail_idx: %d (%"PRId64" %%
>>>> %"PRId64")\n",
>>>> + s->shadow_avail_idx, s->shadow_avail_idx %
>>>> s->vring_num,
>>>> + s->vring_num);
>>>> + monitor_printf(mon, " used_idx: %d (%"PRId64" %%
>>>> %"PRId64")\n",
>>>> + s->used_idx, s->used_idx % s->vring_num,
>>>> s->vring_num);
>>>
>>>
>>> The modular information is not the case of packed ring where the
>>> queue size does not have to be a power of 2.
>> Doesn't modulo work for any integer, regardless if it's a power of 2
>> or not? Could you clarify this for me?
>
>
> For packed ring, the index doesn't increase freely, it's always small
> than the virtqueue size.
>
> So showing the modulo arithmetic seems useless since the device or
> driver doesn't use modulo for calculating the real offset.
>
> Thanks
I see, got it. Thank you for the explanation.
I should be able to easily determine a packed or split ring via.
virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED).
Jonah
>
>
>>
>> Thank you,
>
© 2016 - 2025 Red Hat, Inc.