[PATCH 0/6] qemu: Add support for iothread to virtqueue mapping for 'virtio-scsi'

The qemu part was now merged. Diff to rfc-v2: - The 'ctrl' and 'event' queues are not exposed to be mapped: - dropped patch for named queue support - adapted validation logic - adapted docs Peter Krempa (6): qemucapabilitiestest: Update 'caps_10.0.0_x86_64' to v9.2.0-2799-g0462a32b4f qemu: capabilities: Introduce QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING conf: Add support for iothread to queue mapping config for 'virtio-scsi' qemu: Implement support for iothread <-> virtqueue mapping for 'virtio-scsi' controllers qemuxmlconftest: Add 'iothreads-virtio-scsi-mapping' case NEWS: Mention multiple iothread support for 'virtio-scsi' controller NEWS.rst | 6 + docs/formatdomain.rst | 39 ++++ src/conf/domain_conf.c | 10 +- src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 10 +- src/conf/schemas/domaincommon.rng | 3 + src/hypervisor/domain_driver.c | 3 +- src/qemu/qemu_capabilities.c | 4 + src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_command.c | 6 + src/qemu/qemu_validate.c | 30 ++- .../caps_10.0.0_x86_64.replies | 193 ++++++++++-------- .../caps_10.0.0_x86_64.xml | 7 +- ...ads-virtio-scsi-mapping.x86_64-latest.args | 40 ++++ ...eads-virtio-scsi-mapping.x86_64-latest.xml | 61 ++++++ .../iothreads-virtio-scsi-mapping.xml | 53 +++++ tests/qemuxmlconftest.c | 1 + 17 files changed, 369 insertions(+), 101 deletions(-) create mode 100644 tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.xml -- 2.48.1

Notable changes: - 'virtio-scsi' supports 'iothread-vq-mapping' - 'vfio-pci' device gained two unstable options 'x-igd-legacy-mode' and 'x-igd-lpc' Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- .../caps_10.0.0_x86_64.replies | 193 ++++++++++-------- .../caps_10.0.0_x86_64.xml | 6 +- 2 files changed, 108 insertions(+), 91 deletions(-) diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies index aea8060984..bbb14a06c8 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.replies @@ -20,7 +20,7 @@ "minor": 2, "major": 9 }, - "package": "v9.2.0-2369-g98c7362b1e" + "package": "v9.2.0-2799-g0462a32b4f" }, "id": "libvirt-2" } @@ -24148,7 +24148,7 @@ "parent": "pci-device" }, { - "name": "ClearwaterForest-v1-x86_64-cpu", + "name": "max-x86_64-cpu", "parent": "x86_64-cpu" }, { @@ -24156,7 +24156,7 @@ "parent": "generic-pc-machine" }, { - "name": "Haswell-v1-x86_64-cpu", + "name": "ClearwaterForest-v1-x86_64-cpu", "parent": "x86_64-cpu" }, { @@ -24199,6 +24199,10 @@ "name": "pci-ipmi-bt", "parent": "pci-device" }, + { + "name": "core2duo-x86_64-cpu", + "parent": "x86_64-cpu" + }, { "name": "filter-buffer", "parent": "netfilter" @@ -24216,8 +24220,8 @@ "parent": "pci-vga" }, { - "name": "kvm-pit", - "parent": "pit-common" + "name": "Haswell-v1-x86_64-cpu", + "parent": "x86_64-cpu" }, { "name": "tpm-crb", @@ -24227,14 +24231,14 @@ "name": "rtl8139", "parent": "pci-device" }, - { - "name": "core2duo-x86_64-cpu", - "parent": "x86_64-cpu" - }, { "name": "pci-bridge", "parent": "base-pci-bridge" }, + { + "name": "cxl-rp", + "parent": "pcie-root-port-base" + }, { "name": "pc-q35-2.5-machine", "parent": "generic-pc-machine" @@ -24244,8 +24248,8 @@ "parent": "generic-pc-machine" }, { - "name": "cxl-rp", - "parent": "pcie-root-port-base" + "name": "kvm-pit", + "parent": "pit-common" }, { "name": "virtio-crypto-device", @@ -24308,8 +24312,8 @@ "parent": "virtio-9p-pci-base" }, { - "name": "chardev-pty", - "parent": "chardev" + "name": "chardev-serial", + "parent": "chardev-fd" }, { "name": "virtio-blk-device", @@ -24331,10 +24335,6 @@ "name": "virtio-gpu-gl-device", "parent": "virtio-gpu-device" }, - { - "name": "pc-q35-6.2-machine", - "parent": "generic-pc-machine" - }, { "name": "Westmere-v1-x86_64-cpu", "parent": "x86_64-cpu" @@ -24352,8 +24352,8 @@ "parent": "sys-bus-device" }, { - "name": "PCIE", - "parent": "PCI" + "name": "pc-q35-6.2-machine", + "parent": "generic-pc-machine" }, { "name": "ich9-usb-uhci2", @@ -24364,8 +24364,8 @@ "parent": "generic-pc-machine" }, { - "name": "chardev-serial", - "parent": "chardev-fd" + "name": "Cooperlake-x86_64-cpu", + "parent": "x86_64-cpu" }, { "name": "resettable-container", @@ -24376,8 +24376,8 @@ "parent": "vhost-user-vsock-pci-base" }, { - "name": "Cooperlake-x86_64-cpu", - "parent": "x86_64-cpu" + "name": "kvmclock", + "parent": "sys-bus-device" }, { "name": "ich9-usb-uhci1", @@ -24400,8 +24400,8 @@ "parent": "pci-device" }, { - "name": "kvmclock", - "parent": "sys-bus-device" + "name": "PCIE", + "parent": "PCI" }, { "name": "pc-i440fx-8.2-machine", @@ -24471,14 +24471,14 @@ "name": "ps2-mouse", "parent": "ps2-device" }, - { - "name": "tulip", - "parent": "pci-device" - }, { "name": "xen-xenstore", "parent": "sys-bus-device" }, + { + "name": "tulip", + "parent": "pci-device" + }, { "name": "piix3-ide", "parent": "pci-ide" @@ -24556,8 +24556,8 @@ "parent": "pci-device" }, { - "name": "pc-i440fx-6.0-machine", - "parent": "generic-pc-machine" + "name": "vhost-vsock-pci-non-transitional", + "parent": "vhost-vsock-pci-base" }, { "name": "virtio-9p-device", @@ -24599,6 +24599,10 @@ "name": "pc-q35-7.2-machine", "parent": "generic-pc-machine" }, + { + "name": "pc-i440fx-6.0-machine", + "parent": "generic-pc-machine" + }, { "name": "qemu32-x86_64-cpu", "parent": "x86_64-cpu" @@ -24608,12 +24612,8 @@ "parent": "x86_64-cpu" }, { - "name": "vhost-vsock-pci-non-transitional", - "parent": "vhost-vsock-pci-base" - }, - { - "name": "ich9-usb-ehci2", - "parent": "pci-ehci-usb" + "name": "xen-gnttab", + "parent": "sys-bus-device" }, { "name": "usb-net", @@ -24624,8 +24624,8 @@ "parent": "PCIE" }, { - "name": "xen-gnttab", - "parent": "sys-bus-device" + "name": "ich9-usb-ehci2", + "parent": "pci-ehci-usb" }, { "name": "isa-debug-exit", @@ -25347,10 +25347,6 @@ "name": "xen-bus", "parent": "bus" }, - { - "name": "tls-creds-x509", - "parent": "tls-creds" - }, { "name": "Penryn-v1-x86_64-cpu", "parent": "x86_64-cpu" @@ -25440,8 +25436,8 @@ "parent": "object" }, { - "name": "qio-channel-command", - "parent": "qio-channel" + "name": "tls-creds-x509", + "parent": "tls-creds" }, { "name": "isapc-machine", @@ -25544,8 +25540,8 @@ "parent": "ide-device" }, { - "name": "virtio-pmem", - "parent": "virtio-device" + "name": "qio-channel-command", + "parent": "qio-channel" }, { "name": "Snowridge-v2-x86_64-cpu", @@ -25555,6 +25551,10 @@ "name": "Broadwell-x86_64-cpu", "parent": "x86_64-cpu" }, + { + "name": "acpi-generic-initiator", + "parent": "object" + }, { "name": "vhost-user-scsi-pci", "parent": "vhost-user-scsi-pci-base" @@ -25575,10 +25575,6 @@ "name": "dbus-vmstate", "parent": "object" }, - { - "name": "acpi-generic-initiator", - "parent": "object" - }, { "name": "pc-i440fx-4.1-machine", "parent": "generic-pc-machine" @@ -25592,8 +25588,8 @@ "parent": "e1000-base" }, { - "name": "host-iommu-device-iommufd-vfio", - "parent": "host-iommu-device-iommufd" + "name": "virtio-pmem", + "parent": "virtio-device" }, { "name": "Opteron_G3-v1-x86_64-cpu", @@ -25603,6 +25599,10 @@ "name": "usb-ccid", "parent": "usb-device" }, + { + "name": "host-iommu-device-iommufd-vfio", + "parent": "host-iommu-device-iommufd" + }, { "name": "x-remote-iommu", "parent": "object" @@ -26543,10 +26543,6 @@ "name": "virtio-net-pci", "parent": "virtio-net-pci-base" }, - { - "name": "virtio-vga", - "parent": "virtio-vga-base-type" - }, { "name": "i82558a", "parent": "pci-device" @@ -26583,6 +26579,10 @@ "name": "virtio-mem-pci", "parent": "virtio-mem-pci-base" }, + { + "name": "chardev-pty", + "parent": "chardev" + }, { "name": "SierraForest-v2-x86_64-cpu", "parent": "x86_64-cpu" @@ -26831,6 +26831,10 @@ "name": "sd-bus", "parent": "bus" }, + { + "name": "virtio-vga", + "parent": "virtio-vga-base-type" + }, { "name": "filter-dump", "parent": "netfilter" @@ -26851,10 +26855,6 @@ "name": "smbus-ipmi", "parent": "smbus-device" }, - { - "name": "authz-pam", - "parent": "authz" - }, { "name": "Skylake-Server-v1-x86_64-cpu", "parent": "x86_64-cpu" @@ -26900,8 +26900,8 @@ "parent": "x86_64-cpu" }, { - "name": "max-x86_64-cpu", - "parent": "x86_64-cpu" + "name": "authz-pam", + "parent": "authz" }, { "name": "Dhyana-v2-x86_64-cpu", @@ -28095,6 +28095,11 @@ "description": "on/off", "type": "bool" }, + { + "name": "iothread-vq-mapping", + "description": "IOThread virtqueue mapping list [{\"iothread\":\"<id>\", \"vqs\":[1,2,3,...]},...]", + "type": "IOThreadVirtQueueMappingList" + }, { "default-value": 4294967295, "name": "num_queues", @@ -28313,7 +28318,7 @@ { "default-value": "on", "name": "x-device-dirty-page-tracking", - "description": "Disable device dirty page tracking and use container-based dirty page tracking (DEBUG)", + "description": "Disable device dirty page tracking and use container-based dirty page tracking", "type": "OnOffAuto" }, { @@ -28374,18 +28379,18 @@ "description": "Disable MMAP for device. Allows to trace MMIO accesses (DEBUG)", "type": "bool" }, - { - "default-value": true, - "name": "x-req", - "description": "Disable device request notification support (DEBUG)", - "type": "bool" - }, { "default-value": "off", "name": "x-msix-relocation", "description": "Specify MSI-X MMIO relocation to the end of specified existing BAR or new BAR to avoid virtualization overhead due to adjacent device registers", "type": "OffAutoPCIBAR" }, + { + "default-value": true, + "name": "x-req", + "description": "Disable device request notification support (DEBUG)", + "type": "bool" + }, { "default-value": false, "name": "x-no-kvm-ioeventfd", @@ -28437,6 +28442,12 @@ "description": "Specify UUID VF token. Required for VF when PF is owned by another VFIO driver", "type": "str" }, + { + "default-value": false, + "name": "x-igd-lpc", + "description": "on/off", + "type": "bool" + }, { "default-value": 0, "name": "yres", @@ -28471,6 +28482,12 @@ "description": "Host PCI address [domain:]<bus:slot.function> of assigned device", "type": "str" }, + { + "default-value": "auto", + "name": "x-igd-legacy-mode", + "description": "on/off/auto", + "type": "OnOffAuto" + }, { "default-value": false, "name": "x-no-geforce-quirks", @@ -34951,31 +34968,31 @@ }, { "hotpluggable-cpus": true, - "name": "pc-q35-7.2", + "name": "pc-i440fx-6.0", "numa-mem-supported": false, "default-cpu-type": "qemu64-x86_64-cpu", "acpi": true, - "cpu-max": 288, - "deprecated": false, + "cpu-max": 255, + "deprecated": true, "default-ram-id": "pc.ram" }, { "hotpluggable-cpus": true, - "name": "pc-q35-4.0", - "numa-mem-supported": true, + "name": "pc-q35-7.2", + "numa-mem-supported": false, "default-cpu-type": "qemu64-x86_64-cpu", "acpi": true, "cpu-max": 288, - "deprecated": true, + "deprecated": false, "default-ram-id": "pc.ram" }, { "hotpluggable-cpus": true, - "name": "pc-i440fx-6.0", - "numa-mem-supported": false, + "name": "pc-q35-4.0", + "numa-mem-supported": true, "default-cpu-type": "qemu64-x86_64-cpu", "acpi": true, - "cpu-max": 255, + "cpu-max": 288, "deprecated": true, "default-ram-id": "pc.ram" }, @@ -45190,31 +45207,31 @@ }, { "hotpluggable-cpus": true, - "name": "pc-q35-7.2", + "name": "pc-i440fx-6.0", "numa-mem-supported": false, "default-cpu-type": "qemu64-x86_64-cpu", "acpi": true, - "cpu-max": 288, - "deprecated": false, + "cpu-max": 255, + "deprecated": true, "default-ram-id": "pc.ram" }, { "hotpluggable-cpus": true, - "name": "pc-q35-4.0", - "numa-mem-supported": true, + "name": "pc-q35-7.2", + "numa-mem-supported": false, "default-cpu-type": "qemu64-x86_64-cpu", "acpi": true, "cpu-max": 288, - "deprecated": true, + "deprecated": false, "default-ram-id": "pc.ram" }, { "hotpluggable-cpus": true, - "name": "pc-i440fx-6.0", - "numa-mem-supported": false, + "name": "pc-q35-4.0", + "numa-mem-supported": true, "default-cpu-type": "qemu64-x86_64-cpu", "acpi": true, - "cpu-max": 255, + "cpu-max": 288, "deprecated": true, "default-ram-id": "pc.ram" }, diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml index 24509f6a0a..3a272c8002 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml @@ -208,7 +208,7 @@ <flag name='shim'/> <version>9002050</version> <microcodeVersion>43100285</microcodeVersion> - <package>v9.2.0-2369-g98c7362b1e</package> + <package>v9.2.0-2799-g0462a32b4f</package> <arch>x86_64</arch> <hostCPU type='kvm' model='base' migratability='yes'> <property name='avx-ne-convert' type='boolean' value='false'/> @@ -2146,9 +2146,9 @@ <machine type='kvm' name='pc-q35-9.2' hotplugCpus='yes' maxCpus='4096' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' acpi='yes'/> <machine type='kvm' name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> <machine type='kvm' name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> + <machine type='kvm' name='pc-i440fx-6.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> <machine type='kvm' name='pc-q35-7.2' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' acpi='yes'/> <machine type='kvm' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> - <machine type='kvm' name='pc-i440fx-6.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> <machine type='kvm' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='microvm.ram' acpi='yes'/> <machine type='kvm' name='pc-q35-8.2' hotplugCpus='yes' maxCpus='1024' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' acpi='yes'/> <machine type='kvm' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> @@ -4187,9 +4187,9 @@ <machine type='tcg' name='pc-q35-9.2' hotplugCpus='yes' maxCpus='4096' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' acpi='yes'/> <machine type='tcg' name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> <machine type='tcg' name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> + <machine type='tcg' name='pc-i440fx-6.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> <machine type='tcg' name='pc-q35-7.2' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' acpi='yes'/> <machine type='tcg' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> - <machine type='tcg' name='pc-i440fx-6.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> <machine type='tcg' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='microvm.ram' acpi='yes'/> <machine type='tcg' name='pc-q35-8.2' hotplugCpus='yes' maxCpus='1024' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram' acpi='yes'/> <machine type='tcg' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes' acpi='yes'/> -- 2.48.1

The 'virtio-scsi' controller now supports iothread<->virtqueue mapping configuration. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml | 1 + 3 files changed, 8 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d13b4c8109..0fb231a619 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -729,6 +729,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-mem-ccw", /* QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW */ "blockdev-set-active", /* QEMU_CAPS_BLOCKDEV_SET_ACTIVE */ "shim", /* QEMU_CAPS_MACHINE_SHIM */ + + /* 475 */ + "virtio-scsi.iothread-mapping", /* QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING */ ); @@ -1478,6 +1481,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSpaprPCIHostBrid static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioSCSI[] = { { "acpi-index", QEMU_CAPS_ACPI_INDEX, NULL }, + { "iothread-vq-mapping", QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVfioPCI[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index e836d107aa..68e545c6de 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -709,6 +709,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_BLOCKDEV_SET_ACTIVE, /* blockdev-set-active QMP command supported */ QEMU_CAPS_MACHINE_SHIM, /* -shim command line argument */ + /* 475 */ + QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING, /* virtio-scsi supports per-virtqueue iothread mapping */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml index 3a272c8002..529ec7fbe2 100644 --- a/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_10.0.0_x86_64.xml @@ -206,6 +206,7 @@ <flag name='migrate-incoming.exit-on-error'/> <flag name='blockdev-set-active'/> <flag name='shim'/> + <flag name='virtio-scsi.iothread-mapping'/> <version>9002050</version> <microcodeVersion>43100285</microcodeVersion> <package>v9.2.0-2799-g0462a32b4f</package> -- 2.48.1

Upcoming qemu release will support configuring mapping iothreads to virtio queues for 'virtio-scsi' controllers in order to improve performance. Reuse the infrastructure we have from the same configuration for 'virti-blk' to implement the conf support for this feature. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/formatdomain.rst | 39 +++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 10 +++++++- src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 10 +++++++- src/conf/schemas/domaincommon.rng | 3 +++ src/hypervisor/domain_driver.c | 3 ++- 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c1876ad467..92374ce2f3 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4168,6 +4168,45 @@ An optional sub-element ``driver`` can specify the driver specific options: If a specific IOThread is desired for a specific SCSI ``disk``, then multiple controllers must be defined each having a specific ``iothread`` value. The ``iothread`` value must be within the range 1 to the domain iothreads value. +``iothreads`` + Supported for ``virtio-scsi`` controllers using ``address`` types ``pci`` and + ``ccw``. :since:`since 11.2.0 (QEMU 10.0).` Mutually exclusive with ``iothread``. + + The optional ``iothreads`` sub-element allows specifying multiple IOThreads + via the ``iothread`` sub-element with attribute ``id`` the ``virtio-scsi`` + controller will use for I/O operations. The virt queues (see ``queues`` + attribute of ``driver``) are automatically distributed among the configured + iothreads. + + Optionally the ``iothread`` element can have multiple ``queue`` + subelements with mandatory ``id`` atribute specifying that the iothread + should be used to handle given virt queue. If queue mapping is present + the ``queues`` attribute of ``driver`` must be configured and all + configured virt queues must be included in the mapping. The + ``virtio-scsi`` device exposes request virt queues ``0`` to ``N-1`` where + N is the number of queues configured for the device. + + Example:: + + <driver queues='4> + <iothreads> + <iothread id='2'/> + <iothread id='3'/> + </iothreads> + </driver> + + <driver queues='3'> + <iothreads> + <iothread id='2'> + <queue id='1'/> + </iothread> + <iothread id='3'> + <queue id='0'/> + <queue id='2'/> + </iothread> + </iothreads> + </driver> + virtio options For virtio controllers, `Virtio-related options`_ can also be set. ( :since:`Since 3.5.0` ) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b94cf99236..28d811de1f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2565,6 +2565,8 @@ void virDomainControllerDefFree(virDomainControllerDef *def) if (!def) return; + g_slist_free_full(def->iothreads, (GDestroyNotify) virDomainIothreadMappingDefFree); + virDomainDeviceInfoClear(&def->info); g_free(def->virtio); @@ -8639,6 +8641,9 @@ virDomainControllerDefParseXML(virDomainXMLOption *xmlopt, &def->iothread) < 0) return NULL; + if (virDomainIothreadMappingDefParse(driver, &def->iothreads) < 0) + return NULL; + if (virDomainVirtioOptionsParseXML(driver, &def->virtio) < 0) return NULL; } @@ -23486,6 +23491,7 @@ virDomainControllerDriverFormat(virBuffer *buf, virDomainControllerDef *def) { g_auto(virBuffer) driverBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) driverChildBuf = VIR_BUFFER_INIT_CHILD(buf); if (def->queues) virBufferAsprintf(&driverBuf, " queues='%u'", def->queues); @@ -23504,9 +23510,11 @@ virDomainControllerDriverFormat(virBuffer *buf, if (def->iothread) virBufferAsprintf(&driverBuf, " iothread='%u'", def->iothread); + virDomainIothreadMappingDefFormat(&driverChildBuf, def->iothreads); + virDomainVirtioOptionsFormat(&driverBuf, def->virtio); - virXMLFormatElement(buf, "driver", &driverBuf, NULL); + virXMLFormatElement(buf, "driver", &driverBuf, &driverChildBuf); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a97fd866c..c8a8d17c91 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -764,6 +764,7 @@ struct _virDomainControllerDef { unsigned int max_sectors; virTristateSwitch ioeventfd; unsigned int iothread; /* unused = 0, > 0 specific thread # */ + GSList *iothreads; /* List of virDomainIothreadMappingDef */ union { virDomainVirtioSerialOpts vioserial; virDomainPCIControllerOpts pciopts; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index f2a98f143d..33c3a3ffcc 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1267,7 +1267,7 @@ virDomainControllerDefValidate(const virDomainControllerDef *controller) } } - if (controller->iothread != 0) { + if (controller->iothread != 0 || controller->iothreads) { if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI || !(controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI || controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL || @@ -1276,6 +1276,14 @@ virDomainControllerDefValidate(const virDomainControllerDef *controller) _("iothreads are supported only by 'virtio-scsi' controllers")); return -1; } + + /* configuring both <driver iothread='n'> and it's <iothreads> sub-element + * isn't supported */ + if (controller->iothread && controller->iothreads) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("controller driver 'iothread' attribute can't be used together with 'iothreads' subelement")); + return -1; + } } return 0; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 3276569325..e4f4626b33 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -3064,6 +3064,9 @@ <optional> <ref name="driverIOThread"/> </optional> + <optional> + <ref name="iothreadMapping"/> + </optional> <ref name="virtioOptions"/> </element> </optional> diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index b7499a376f..29ba358477 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -585,7 +585,8 @@ virDomainDriverDelIOThreadCheck(virDomainDef *def, } for (i = 0; i < def->ncontrollers; i++) { - if (def->controllers[i]->iothread == iothread_id) { + if (virDomainIothreadMappingDefHasIothread(def->controllers[i]->iothreads, iothread_id) || + def->controllers[i]->iothread == iothread_id) { virReportError(VIR_ERR_INVALID_ARG, _("cannot remove IOThread '%1$u' since it is being used by controller"), iothread_id); -- 2.48.1

Similarly to 'virtio-blk' users can map multiple iothreads and pin them appropriately for 'virtio-scsi' controllers to ensure the best performance. Implement the validation and command line generation based on the helpers we have for 'virtio-blk'. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 6 ++++++ src/qemu/qemu_validate.c | 30 +++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 51e428e017..4c87a74d0e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2505,6 +2505,7 @@ qemuBuildControllerSCSIDevProps(virDomainControllerDef *def, virQEMUCaps *qemuCaps) { g_autoptr(virJSONValue) props = NULL; + g_autoptr(virJSONValue) iothreadsMapping = NULL; g_autofree char *iothread = NULL; const char *driver = NULL; @@ -2516,6 +2517,10 @@ qemuBuildControllerSCSIDevProps(virDomainControllerDef *def, qemuCaps))) return NULL; + if (def->iothreads && + !(iothreadsMapping = qemuBuildIothreadMappingProps(def->iothreads))) + return NULL; + if (def->iothread > 0) iothread = g_strdup_printf("iothread%u", def->iothread); @@ -2523,6 +2528,7 @@ qemuBuildControllerSCSIDevProps(virDomainControllerDef *def, "S:iothread", iothread, "s:id", def->info.alias, "p:num_queues", def->queues, + "A:iothread-vq-mapping", &iothreadsMapping, "p:cmd_per_lun", def->cmd_per_lun, "p:max_sectors", def->max_sectors, "T:ioeventfd", def->ioeventfd, diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 4ef944addb..1220c5dca0 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3657,9 +3657,10 @@ qemuValidateDomainDeviceDefControllerIDE(const virDomainControllerDef *controlle */ static int qemuValidateCheckSCSIControllerIOThreads(const virDomainControllerDef *controller, - const virDomainDef *def) + const virDomainDef *def, + virQEMUCaps *qemuCaps) { - if (!controller->iothread) + if (controller->iothread == 0 && !controller->iothreads) return 0; if (controller->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -3670,8 +3671,20 @@ qemuValidateCheckSCSIControllerIOThreads(const virDomainControllerDef *controlle return -1; } - /* Can we find the controller iothread in the iothreadid list? */ - if (!virDomainIOThreadIDFind(def, controller->iothread)) { + if (controller->iothreads) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("IOThread mapping for virtio-scsi controllers is not available with this QEMU binary")); + return -1; + } + + if (qemuDomainValidateIothreadMapping(def, controller->iothreads, + controller->queues) < 0) + return -1; + } + + if (controller->iothread > 0 && + !virDomainIOThreadIDFind(def, controller->iothread)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("controller iothread '%1$u' not defined in iothreadid"), controller->iothread); @@ -3684,13 +3697,15 @@ qemuValidateCheckSCSIControllerIOThreads(const virDomainControllerDef *controlle static int qemuValidateDomainDeviceDefControllerSCSI(const virDomainControllerDef *controller, - const virDomainDef *def) + const virDomainDef *def, + virQEMUCaps *qemuCaps) { switch ((virDomainControllerModelSCSI) controller->model) { case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL: - if (qemuValidateCheckSCSIControllerIOThreads(controller, def) < 0) + if (qemuValidateCheckSCSIControllerIOThreads(controller, def, + qemuCaps) < 0) return -1; break; @@ -4364,7 +4379,8 @@ qemuValidateDomainDeviceDefController(const virDomainControllerDef *controller, break; case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: - ret = qemuValidateDomainDeviceDefControllerSCSI(controller, def); + ret = qemuValidateDomainDeviceDefControllerSCSI(controller, def, + qemuCaps); break; case VIR_DOMAIN_CONTROLLER_TYPE_PCI: -- 2.48.1

Test the XML and commandline for iothread<->virtqueue mapping for 'virtio-scsi' controllers. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- ...ads-virtio-scsi-mapping.x86_64-latest.args | 40 ++++++++++++ ...eads-virtio-scsi-mapping.x86_64-latest.xml | 61 +++++++++++++++++++ .../iothreads-virtio-scsi-mapping.xml | 53 ++++++++++++++++ tests/qemuxmlconftest.c | 1 + 4 files changed, 155 insertions(+) create mode 100644 tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.xml diff --git a/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.args b/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.args new file mode 100644 index 0000000000..c4491cd995 --- /dev/null +++ b/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.args @@ -0,0 +1,40 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-accel tcg \ +-cpu qemu64 \ +-m size=219136k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-overcommit mem-lock=off \ +-smp 2,sockets=2,cores=1,threads=1 \ +-object '{"qom-type":"iothread","id":"iothread1"}' \ +-object '{"qom-type":"iothread","id":"iothread2"}' \ +-object '{"qom-type":"iothread","id":"iothread3"}' \ +-object '{"qom-type":"iothread","id":"iothread4"}' \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-device '{"driver":"virtio-scsi-pci","id":"scsi0","num_queues":3,"iothread-vq-mapping":[{"iothread":"iothread2"},{"iothread":"iothread3"}],"bus":"pci.0","addr":"0xb"}' \ +-device '{"driver":"virtio-scsi-pci","id":"scsi1","num_queues":2,"iothread-vq-mapping":[{"iothread":"iothread4","vqs":[0]},{"iothread":"iothread2","vqs":[1]}],"bus":"pci.0","addr":"0xc"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/iothrtest2.img","node-name":"libvirt-1-storage","read-only":false}' \ +-device '{"driver":"scsi-hd","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":3,"device_id":"drive-scsi0-0-0-3","drive":"libvirt-1-storage","id":"scsi0-0-0-3","bootindex":1}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.xml b/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.xml new file mode 100644 index 0000000000..11f0aff401 --- /dev/null +++ b/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.x86_64-latest.xml @@ -0,0 +1,61 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>2</vcpu> + <iothreads>4</iothreads> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/iothrtest2.img'/> + <target dev='sdc' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='3'/> + </disk> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='scsi' index='0' model='virtio-scsi'> + <driver queues='3'> + <iothreads> + <iothread id='2'/> + <iothread id='3'/> + </iothreads> + </driver> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </controller> + <controller type='scsi' index='1' model='virtio-scsi'> + <driver queues='2'> + <iothreads> + <iothread id='4'> + <queue id='0'/> + </iothread> + <iothread id='2'> + <queue id='1'/> + </iothread> + </iothreads> + </driver> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.xml b/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.xml new file mode 100644 index 0000000000..e8deeed26e --- /dev/null +++ b/tests/qemuxmlconfdata/iothreads-virtio-scsi-mapping.xml @@ -0,0 +1,53 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>2</vcpu> + <iothreads>4</iothreads> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/iothrtest2.img'/> + <target dev='sdc' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='0' unit='3'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <controller type='scsi' index='0' model='virtio-scsi'> + <driver queues='3'> + <iothreads> + <iothread id='2'/> + <iothread id='3'/> + </iothreads> + </driver> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </controller> + <controller type='scsi' index='1' model='virtio-scsi'> + <driver queues='2'> + <iothreads> + <iothread id='4'> + <queue id='0'/> + </iothread> + <iothread id='2'> + <queue id='1'/> + </iothread> + </iothreads> + </driver> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 43ba9fed82..6f277f87eb 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2186,6 +2186,7 @@ mymain(void) DO_TEST_CAPS_LATEST("iothreads-ids-pool-sizes"); DO_TEST_CAPS_LATEST("iothreads-disk"); DO_TEST_CAPS_LATEST("iothreads-virtio-scsi-pci"); + DO_TEST_CAPS_LATEST("iothreads-virtio-scsi-mapping"); DO_TEST_CAPS_ARCH_LATEST("iothreads-virtio-scsi-ccw", "s390x"); DO_TEST_CAPS_LATEST("cpu-topology1"); -- 2.48.1

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- NEWS.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 9c940b1a81..37233121b6 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -17,6 +17,12 @@ v11.2.0 (unreleased) * **New features** + * qemu: Add support for multiple iothreads for ``virtio-scsi`` controller + + It's now possible to map multiple iotreads to the ``virtio-scsi`` controller + or even map them to specific virtqueues similarly to the ``virtio-blk`` + device allowing for better performance in certain scenarios. + * **Improvements** * **Bug fixes** -- 2.48.1

On a Friday in 2025, Peter Krempa wrote:
The qemu part was now merged.
Diff to rfc-v2: - The 'ctrl' and 'event' queues are not exposed to be mapped: - dropped patch for named queue support - adapted validation logic - adapted docs
Peter Krempa (6): qemucapabilitiestest: Update 'caps_10.0.0_x86_64' to v9.2.0-2799-g0462a32b4f qemu: capabilities: Introduce QEMU_CAPS_VIRTIO_SCSI_IOTHREAD_MAPPING conf: Add support for iothread to queue mapping config for 'virtio-scsi' qemu: Implement support for iothread <-> virtqueue mapping for 'virtio-scsi' controllers qemuxmlconftest: Add 'iothreads-virtio-scsi-mapping' case NEWS: Mention multiple iothread support for 'virtio-scsi' controller
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa