diff mbox series

[RFC,14/22] arm/cpuhp: Release objects for *disabled* possible vcpus after init

Message ID 20200613213629.21984-15-salil.mehta@huawei.com
State New
Headers show
Series Support of Virtual CPU Hotplug for ARMv8 Arch | expand

Commit Message

Salil Mehta June 13, 2020, 9:36 p.m. UTC
During machvirt_init(), ARMCPU objects are pre-created along with the
corresponding KVM vcpus in the host. Disabled possible KVM vcpus are then
parked at the per-virt-machine list "kvm_parked_vcpus".

Prime purpose to pre-create ARMCPU objects for the disabled vcpus is to
facilitate the GIC initialization (pre-sized with possible vcpus). GIC
requires all vcpus corresponding to its GICC(GIC CPU Interface) to be
initialized and present during its own initialization.

After initialization of the machine is complete we release the ARMCPU objects
for the disabled vcpus(which shall be re-created at the time when vcpu is hot
plugged again. This newly created ARMCPU object is then attached with
corresponding parked KVM VCPU).

We have few options after the machine init where the disabled ARMCPU object
could be released:
1. Release in context to the virt_machine_done() notifier.(This is also our
   current approach)
2. Defer the release till a new vcpu object is hot plugged. Then release the
   object in context to the pre_plug() phase.
3. Never release and keep on reusing them and release once at VM exit. This
   will require some modifications within the interface of qdevice_add() to
   get old ARMCPU object instead of creating a new one for the hotplug request.

Each of the above approaches come with their own pros and cons. This prototype
uses the 1st approach.(suggestions are welcome!)

Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>

---
 hw/arm/virt.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

-- 
2.17.1
diff mbox series

Patch

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e9ead0e2dd..0faf54aa8f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1403,6 +1403,28 @@  static void create_secure_ram(VirtMachineState *vms,
     g_free(nodename);
 }
 
+static void virt_remove_disabled_cpus(VirtMachineState *vms)
+{
+    MachineState *ms = MACHINE(vms);
+    int n;
+
+    /*
+     * RFC: Question: Other approach could have been to keep them forever
+     * and release it only once when qemu exits as part o finalize or when
+     * new vcpu is hotplugged. In the later old could be released for the
+     * newly created object for the same vcpu?
+     */
+    for (n = vms->smp_cpus; n < vms->max_cpus; n++) {
+        CPUState *cs = qemu_get_possible_cpu(n);
+        if (!qemu_present_cpu(cs)) {
+            CPUArchId *cpu_slot;
+            cpu_slot = virt_find_cpu_slot(ms, cs->cpu_index);
+            cpu_slot->cpu = NULL;
+            object_unref(OBJECT(cs));
+        }
+    }
+}
+
 static bool virt_pmu_init(VirtMachineState *vms)
 {
     CPUArchIdList *possible_cpus = vms->parent.possible_cpus;
@@ -1500,6 +1522,9 @@  void virt_machine_done(Notifier *notifier, void *data)
 
     virt_acpi_setup(vms);
     virt_build_smbios(vms);
+
+    /* release the disabled ARMCPU objects used during init for pre-sizing */
+     virt_remove_disabled_cpus(vms);
 }
 
 static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)