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}