Hi, This is an attempt to define a generic CPU device that serves as a containing device to underlying arch-specific CPU devices. The motivation for this is to have an arch-neutral way to specify CPUs mainly during hotplug.
Instead of individual archs having their own semantics to specify the CPU like -device POWER8-powerpc64-cpu (pseries) -device qemu64-x86_64-cpu (pc) -device s390-cpu (s390) this patch introduces a new device named cpu-core that could be used for all target archs as -device cpu-core,socket="sid" This adds a CPU core with all its associated threads into the specified socket with id "sid". The number of target architecture specific CPU threads that get created during this operation is based on the CPU topology specified using -smp sockets=S,cores=C,threads=T option. Also the number of cores that can be accommodated in the same socket is dictated by the cores= parameter in the same -smp option. CPU sockets are represented by QOM objects and the number of sockets required to fit in max_cpus are created at boottime. As cpu-core devices are created, they are linked to socket object specified by socket="sid" device property. Thus the model consists of backend socket objects which can be considered as container of one or more cpu-core devices. Each cpu-core object is linked to the appropriate backend socket object. Each CPU thread device appears as child object of cpu-core device. All the required socket objects are created upfront and they can't be deleted. Though currently socket objects can be created using object_add monitor command, I am planning to prevent that so that a guest boots with the required number of sockets and only CPU cores can be hotplugged into them. CPU hotplug granularity ----------------------- CPU hotplug will now be done in cpu-core device granularity. This patchset includes a patch to prevent topologies that result in partially filled cores. Hence with this patchset, we will always have fully filled cpu-core devices both for boot time and during hotplug. For archs like PowerPC, where there is no requirement to be fully similar to the physical system, hotplugging CPU at core granularity is common. While core level hotplug will fit in naturally for such archs, for others which want socket level hotplug, could higher level tools like libvirt perform multiple core hotplugs in response to one socket hotplug request ? Are there archs that would need thread level CPU addition ? Boot time CPUs as cpu-core devices ---------------------------------- In this patchset, I am coverting the boot time CPU initialization (from -smp option) to initialize the required number of cpu-core devices and linking them with the appropriate socket objects. Initially I thought we should be able to completely replace -smp with -device cpu-core, but then I realized that at least both x86 and pseries guests' machine init code has dependencies on first CPU being available for the machine init code to work correctly. Currently I have converted boot CPUs to cpu-core devices only PowerPC sPAPR and i386 PC targets. I am not really sure about the i386 changes and the intention in this iteration was to check if it is indeed possible to fit i386 into cpu-core model. Having said that I am able to boot an x86 guest with this patchset. NUMA ---- TODO: In this patchset, I haven't explicitly done anything for NUMA yet. I am thinking if we could add node=N option to cpu-core device. That could specify the NUMA node to which the CPU core belongs to. -device cpu-core,socket="sid",node=N QOM composition tree --------------------- QOM composition tree for x86 where I don't have CPU hotplug enabled, but just initializing boot CPUs as cpu-core devices appears like this: -smp 4,sockets=4,cores=2,threads=2,maxcpus=16 /machine (pc-i440fx-2.5-machine) /unattached (container) /device[0] (cpu-core) /thread[0] (qemu64-x86_64-cpu) /thread[1] (qemu64-x86_64-cpu) /device[4] (cpu-core) /thread[0] (qemu64-x86_64-cpu) /thread[1] (qemu64-x86_64-cpu) For PowerPC where I have CPU hotplug enabled: -smp 4,sockets=4,cores=2,threads=2,maxcpus=16 -device cpu-core,socket=cpu-socket1,id=core3 /machine (pseries-2.5-machine) /unattached (container) /device[1] (cpu-core) /thread[0] (host-powerpc64-cpu) /thread[1] (host-powerpc64-cpu) /device[2] (cpu-core) /thread[0] (host-powerpc64-cpu) /thread[1] (host-powerpc64-cpu) /peripheral (container) /core3 (cpu-core) /thread[0] (host-powerpc64-cpu) /thread[1] (host-powerpc64-cpu) As can be seen, the boot CPU and hotplugged CPU come under separate parents. Guess I should work towards getting both boot time and hotplugged CPUs under same parent ? Socket ID generation --------------------- In the current approach the socket ID generation is implicit somewhat. All the sockets objects are created with pre-fixed format for ids like cpu-socket0, cpu-socket1 etc. And machine init code of each arch is expected to use the same when creating cpu-core devices to link the core to the right object. Even user needs to know these IDs during device_add time. May be I could add "info cpu-sockets" which gives information about all the existing sockets and their core-occupancy status. Finally, I understand that this is a simplistic model and it wouldn't probably support all the notions around CPU topology and hotplug that we would like to support for all archs. The intention of this RFC is to start with somewhere and seek inputs from the community. Bharata B Rao (9): vl: Don't allow CPU toplogies with partially filled cores cpu: Store CPU typename in MachineState cpu: Don't realize CPU from cpu_generic_init() cpu: CPU socket backend vl: Create CPU socket backend objects cpu: Introduce CPU core device spapr: Convert boot CPUs into CPU core device initialization target-i386: Set apic_id during CPU initfn pc: Convert boot CPUs into CPU core device initialization hw/cpu/Makefile.objs | 1 + hw/cpu/core.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ hw/cpu/socket.c | 48 ++++++++++++++++++++++ hw/i386/pc.c | 64 +++++++++-------------------- hw/ppc/spapr.c | 32 ++++++++++----- include/hw/boards.h | 1 + include/hw/cpu/core.h | 28 +++++++++++++ include/hw/cpu/socket.h | 26 ++++++++++++ qom/cpu.c | 6 --- target-arm/helper.c | 16 +++++++- target-cris/cpu.c | 16 +++++++- target-i386/cpu.c | 37 ++++++++++++++++- target-i386/cpu.h | 1 + target-lm32/helper.c | 16 +++++++- target-moxie/cpu.c | 16 +++++++- target-openrisc/cpu.c | 16 +++++++- target-ppc/translate_init.c | 16 +++++++- target-sh4/cpu.c | 16 +++++++- target-tricore/helper.c | 16 +++++++- target-unicore32/helper.c | 16 +++++++- vl.c | 26 ++++++++++++ 21 files changed, 439 insertions(+), 73 deletions(-) create mode 100644 hw/cpu/core.c create mode 100644 hw/cpu/socket.c create mode 100644 include/hw/cpu/core.h create mode 100644 include/hw/cpu/socket.h -- 2.1.0