Hi, Attached is the patch for addition of "cpu-del" command over and above the below patches for hot removing the cpu.
[RFC PATCH 0/7] i386: add cpu hot remove support [RFC PATCH 1/7] x86: add x86_cpu_unrealizefn() for cpu apic remove [RFC PATCH 2/7] i386: add cpu device_del support [RFC PATCH 3/7] qom cpu: rename variable 'cpu_added_notifier' to 'cpu_hotplug_notifier' [RFC PATCH 4/7] qom cpu: add UNPLUG cpu notify support [RFC PATCH 5/7] i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c [RFC PATCH 6/7] cpu hotplug: implement function cpu_status_write() for vcpu ejection [RFC PATCH 7/7] cpus: reclaim allocated vCPU objects Useful, just in case if anyone wants to continue with the old / compatible "cpu-del" command. Patch for addition of "cpu-del" command: +++ b/include/hw/boards.h @@ -25,6 +25,8 @@ typedef void QEMUMachineResetFunc(void); typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp); +typedef void QEMUMachineHotDelCPUFunc(const int64_t id, Error **errp); + typedef int QEMUMachineGetKvmtypeFunc(const char *arg); struct QEMUMachine { @@ -34,6 +36,7 @@ struct QEMUMachine { QEMUMachineInitFunc *init; QEMUMachineResetFunc *reset; QEMUMachineHotAddCPUFunc *hot_add_cpu; + QEMUMachineHotDelCPUFunc *hot_del_cpu; QEMUMachineGetKvmtypeFunc *kvm_type; BlockInterfaceType block_default_type; int max_cpus; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index f2d39d2..33350fc 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -163,6 +163,7 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); void pc_hot_add_cpu(const int64_t id, Error **errp); +void pc_hot_del_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, @@ -472,6 +473,7 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); #define PC_DEFAULT_MACHINE_OPTIONS \ PC_COMMON_MACHINE_OPTIONS, \ .hot_add_cpu = pc_hot_add_cpu, \ + .hot_del_cpu = pc_hot_del_cpu, \ .max_cpus = 255 #endif diff --git a/qmp.c b/qmp.c index 95369f9..fc494da 100644 --- a/qmp.c +++ b/qmp.c @@ -126,6 +126,18 @@ void qmp_cpu_add(int64_t id, Error **errp) } } +void qmp_cpu_del(int64_t id, Error **errp) +{ + MachineClass *mc; + mc = MACHINE_GET_CLASS(current_machine); + if (mc->qemu_machine->hot_del_cpu) { + mc->qemu_machine->hot_del_cpu(id, errp); + } + else { + error_setg(errp, "Not supported"); + } +} + #ifndef CONFIG_VNC /* If VNC support is enabled, the "true" query-vnc command is defined in the VNC subsystem */ hw/i386/pc.c +void pc_hot_del_cpu(const int64_t id, Error **errp) +{ + int64_t apic_id = x86_cpu_apic_id_from_index(id); + fprintf(stderr, "pc.c: pc_hot_del_cpu for apic_id = %d\n", apic_id); + + if (id < 0) { + error_setg(errp, "Invalid CPU id: %" PRIi64, id); + return; + } + + if (!cpu_exists(apic_id)) { + error_setg(errp, "Unable to remove CPU: %" PRIi64 + ", it does not exists", id); + return; + } + + if (id >= max_cpus) { + error_setg(errp, "Unable to remove CPU: %" PRIi64 + ", max allowed: %d", id, max_cpus - 1); + return; + } + + CPUState *cpu = first_cpu; + X86CPUClass *xcc = NULL; + while (cpu = CPU_NEXT(cpu)) { + fprintf(stderr, "cpu threa_id = %d, cpu_index = %d\n", cpu->thread_id, cpu->cpu_index); + if ((cpu->cpu_index + 1) == apic_id) + break; + } if (cpu == first_cpu) { fprintf(stderr, "Unable to delete the last one cpu.\n"); return; } xcc = X86_CPU_GET_CLASS(DEVICE(cpu)); xcc->parent_unrealize(DEVICE(cpu), errp); } Anshul Makkar wwwdotjustkerneldotcom