On Fri, Nov 20, 2015 at 06:24:38PM +0530, Bharata B Rao wrote: > Support hot removal of CPU for sPAPR guests by sending the hot unplug > notification to the guest via EPOW interrupt. Release the vCPU object > after CPU hot unplug so that vCPU fd can be parked and reused. > > Signed-off-by: Bharata B Rao <bhar...@linux.vnet.ibm.com> > --- > hw/ppc/spapr.c | 71 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 71 insertions(+) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 4434d45..6dca553 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -2401,11 +2401,82 @@ static void spapr_machine_device_plug(HotplugHandler > *hotplug_dev, > } > } > > +static void spapr_cpu_destroy(PowerPCCPU *cpu) > +{ > + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); > + > + xics_cpu_destroy(spapr->icp, cpu); > + qemu_unregister_reset(spapr_cpu_reset, cpu); > +} > + > +static void spapr_cpu_release(DeviceState *dev, void *opaque)
I'd prefer to see this called "core_release" since "cpu" doesn't make it clear that it's acting on a whole core. > +{ > + CPUState *cs; > + int i; > + int id = ppc_get_vcpu_dt_id(POWERPC_CPU(CPU(dev))); > + > + for (i = id; i < id + smp_threads; i++) { > + CPU_FOREACH(cs) { > + PowerPCCPU *cpu = POWERPC_CPU(cs); > + > + if (i == ppc_get_vcpu_dt_id(cpu)) { > + spapr_cpu_destroy(cpu); > + cpu_remove(cs); > + } > + } > + } > +} > + > +static int spapr_cpu_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, > + Error **errp) > +{ > + CPUState *cs = CPU(dev); > + PowerPCCPU *cpu = POWERPC_CPU(cs); > + int id = ppc_get_vcpu_dt_id(cpu); > + int smt = kvmppc_smt_threads(); > + sPAPRDRConnector *drc = > + spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id); > + sPAPRDRConnectorClass *drck; > + Error *local_err = NULL; > + > + /* > + * SMT threads return from here, only main thread (core) will > + * continue and signal hot unplug event to the guest. > + */ > + if ((id % smt) != 0) { > + return 0; > + } > + g_assert(drc); > + > + drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); > + drck->detach(drc, dev, spapr_cpu_release, NULL, &local_err); > + if (local_err) { > + error_propagate(errp, local_err); > + return -1; > + } > + > + /* > + * In addition to hotplugged CPUs, send the hot-unplug notification > + * interrupt to the guest for coldplugged CPUs started via -device > + * option too. > + */ > + spapr_hotplug_req_remove_by_index(drc); > + return 0; > +} > + > static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, > DeviceState *dev, Error **errp) > { > + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine()); > + > if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { > error_setg(errp, "Memory hot unplug not supported by sPAPR"); > + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { > + if (!smc->dr_cpu_enabled) { > + error_setg(errp, "CPU hot unplug not supported on this machine"); > + return; > + } > + spapr_cpu_unplug(hotplug_dev, dev, errp); > } > } > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature