Changelog --------- Changes v3 -> v4: * New compact representation of slot sets. * New generic code to automatically merge similar slots into a single entry in the command output while keeping implementations of the method simpler. * Example implementation of IDE and USB bus enumeration Changes v2 -> v3: * Implemented a "slot set" structure, where multiple slots can be reported by using integer ranges or lists for possible values for each property. Added a ValueSet struct, that can represent a set of values using either a simple list of values, or integer ranges. (Its JSON representation is very verbose, though. See comments below). * Removed the *Properties structs, and replaced them with a simple list of SlotOption structs. * DeviceSlotInfo is not an union anymore, removed the 'type' field only because there are no slot-type-specific fields in the current implementation, but we may add it back if necessary * The implementation is very quick and dirty, the main purpose of this RFC is to evaluate the schema and returned data. Changes v1 -> v2: * Don't show sysbus unless has_dynamic_sysbus is set for the machine type * Removed max-devices and devices properties * Introduced "non-slot" slot type, to explicitly indicate we are returning info on a bus that doesn't implement slot enumeration yet. * Return bus name instead of full QOM path on "bus" field * PCI: Replaced "addr" property (string parsed by property setter) with "device-number" uint32 property * PCI: return only one slot for PCIe ports Summary ------- This adds a new command to QMP: query-device-slots. It will allow management software to query possible slots where devices can be plugged. This implementation of the command will return: * Multiple PCI slots per bus, in the case of PCI buses; * One slot for each entry from query-hotpluggable-cpus. * One slot per bus for the other buses (that don't implement slot enumeration yet), with opts-complete=false Representation of slot sets in JSON ----------------------------------- Slot sets are represented by a list of option names and sets of possible values for each of those options. The command uses a compact representation for the set of valid values for an option. For example, the following set of 5 PCI functions: bus: pcie.0 device-number: 31 functions: 1,4,5,6,7 would be represented in the JSON data as: {"available":false,"count":5, "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":[1,[4,7]]}, {"option":"device-number","values":31}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} I planned to use QAPI alternates to model/document that in the schema, but it would require implementing a few missing features in QAPI alternate support. TODO ---- * Differentiation between legacy-pci-device and pcie-device * Implement enumeration for other buses * Document the slotinfo.c functions * Optimize the slot/option merging algorithm Example output -------------- Using the following QEMU command-line: $ qemu-system-x86_64 -machine q35,accel=kvm \ -smp 16,maxcpus=32,threads=2,cores=2 query-device-slots will return the following entries: {"available":true,"count":224, "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":[[0,7]]}, {"option":"device-number","values":[[3,30]]}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":true,"count":1, "device-types":["ide-device"],"hotpluggable":false, "opts":[ {"option":"unit","values":0}, {"option":"bus","values":"ide.2"}], "opts-complete":true} {"available":true,"count":10, "device-types":["ide-device"],"hotpluggable":false, "opts":[ {"option":"unit","values":[[0,1]]}, {"option":"bus","values":["ide.4","ide.3","ide.5","ide.0","ide.1"]}], "opts-complete":true} {"available":true, "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":true,"count":16, "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":[[4,7]]}, {"option":"thread-id","values":[[0,1]]}, {"option":"core-id","values":[[0,1]]}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[16]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":3}, {"option":"thread-id","values":1}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[15]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":3}, {"option":"thread-id","values":0}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[14]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":3}, {"option":"thread-id","values":1}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[13]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":3}, {"option":"thread-id","values":0}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[12]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":2}, {"option":"thread-id","values":1}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[11]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":2}, {"option":"thread-id","values":0}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[10]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":2}, {"option":"thread-id","values":1}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[9]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":2}, {"option":"thread-id","values":0}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[8]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":1}, {"option":"thread-id","values":1}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[7]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":1}, {"option":"thread-id","values":0}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[6]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":1}, {"option":"thread-id","values":1}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[5]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":1}, {"option":"thread-id","values":0}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[4]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":0}, {"option":"thread-id","values":1}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[3]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":0}, {"option":"thread-id","values":0}, {"option":"core-id","values":1}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[2]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":0}, {"option":"thread-id","values":1}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[0]", "device-types":["qemu64-x86_64-cpu"],"hotpluggable":true, "opts":[ {"option":"socket-id","values":0}, {"option":"thread-id","values":0}, {"option":"core-id","values":0}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/q35/mch", "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":0}, {"option":"device-number","values":0}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":21, "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":[[1,7]]}, {"option":"device-number","values":[[0,2]]}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[44]", "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":0}, {"option":"device-number","values":1}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[45]", "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":0}, {"option":"device-number","values":2}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[18]", "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":0}, {"option":"device-number","values":31}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":5, "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":[1,[4,7]]}, {"option":"device-number","values":31}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[33]", "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":2}, {"option":"device-number","values":31}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[35]", "device-types":["pci-device"],"hotpluggable":false, "opts":[ {"option":"function","values":3}, {"option":"device-number","values":31}, {"option":"bus","values":"pcie.0"}], "opts-complete":true} {"available":false,"count":1,"device":"/machine/unattached/device[34]", "device-types":["ide-device"],"hotpluggable":false, "opts":[ {"option":"unit","values":1}, {"option":"bus","values":"ide.2"}], "opts-complete":true} {"available":false,"device":"/machine/unattached/device[32]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[31]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[30]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[29]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[28]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[27]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[26]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[25]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[24]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[23]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[22]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[20]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} {"available":false,"device":"/machine/unattached/device[19]", "device-types":["isa-device"],"hotpluggable":false, "opts":[ {"option":"bus","values":"isa.0"}], "opts-complete":false} Cc: Markus Armbruster <armbru@xxxxxxxxxx> Cc: Marcel Apfelbaum <marcel@xxxxxxxxxx> Cc: libvir-list@xxxxxxxxxx Cc: Igor Mammedov <imammedo@xxxxxxxxxx> Cc: Laine Stump <laine@xxxxxxxxxx> Eduardo Habkost (13): qmp: Define query-device-slots command qapi: qobject_compare() helper qdev: Add BusClass::device_type field qdev: Slot info helpers query-device-slots: Collapse similar entries qdev core: generic enumerate_slots implementation qdev: Enumerate CPU slots on query-device-slots ide: enumerate_slots implementation pci: pci_bus_has_pcie_upstream_port() function pci: device-number & function properties pci: enumerate_slots implementation usb: enumerate_slots implementation tests: Experimental query-device-slots test code qapi-schema.json | 89 ++++++ include/hw/qdev-core.h | 5 + include/hw/qdev-slotinfo.h | 85 ++++++ include/hw/usb.h | 6 +- include/qapi/util.h | 39 +++ hw/audio/intel-hda.c | 7 + hw/block/fdc.c | 15 +- hw/char/virtio-serial-bus.c | 1 + hw/core/bus.c | 42 +++ hw/core/slotinfo.c | 610 ++++++++++++++++++++++++++++++++++++++++++ hw/core/sysbus.c | 8 + hw/i2c/core.c | 7 + hw/ide/qdev.c | 27 ++ hw/input/adb.c | 7 + hw/ipack/ipack.c | 7 + hw/isa/isa-bus.c | 1 + hw/misc/auxbus.c | 1 + hw/pci/pci.c | 120 ++++++++- hw/ppc/spapr_vio.c | 1 + hw/s390x/css-bridge.c | 2 + hw/s390x/event-facility.c | 1 + hw/s390x/s390-pci-bus.c | 7 + hw/scsi/scsi-bus.c | 1 + hw/sd/core.c | 7 + hw/ssi/ssi.c | 7 + hw/usb/bus.c | 37 +++ hw/usb/dev-smartcard-reader.c | 7 + hw/virtio/virtio-bus.c | 1 + qapi/qapi-util.c | 66 +++++ qdev-monitor.c | 109 ++++++++ tests/test-qapi-util.c | 53 ++++ tests/test-slotinfo.c | 398 +++++++++++++++++++++++++++ hw/core/Makefile.objs | 2 + tests/Makefile.include | 14 +- tests/qmp-machine-info.py | 300 +++++++++++++++++++++ 35 files changed, 2075 insertions(+), 15 deletions(-) create mode 100644 include/hw/qdev-slotinfo.h create mode 100644 hw/core/slotinfo.c create mode 100644 tests/test-slotinfo.c create mode 100755 tests/qmp-machine-info.py -- 2.9.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list