[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v6 11/11] spapr: CPU hot unplug support
From: |
Bharata B Rao |
Subject: |
Re: [Qemu-devel] [PATCH v6 11/11] spapr: CPU hot unplug support |
Date: |
Wed, 13 Jan 2016 09:40:54 +0530 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
On Tue, Jan 12, 2016 at 05:06:34PM +1100, David Gibson wrote:
> On Fri, Jan 08, 2016 at 12:25:19PM +0530, Bharata B Rao wrote:
> > Remove the CPU core device by removing the underlying CPU thread devices.
> > 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 <address@hidden>
> > ---
> > hw/ppc/spapr.c | 113
> > +++++++++++++++++++++++++++++++++++++++++++++++++
> > include/hw/ppc/spapr.h | 6 +++
> > 2 files changed, 119 insertions(+)
> >
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index c2af9ca..43cb726 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -93,6 +93,9 @@
> >
> > #define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift))
> >
> > +static QLIST_HEAD(cpu_unplug_list, sPAPRCPUUnplug) cpu_unplug_list
> > + = QLIST_HEAD_INITIALIZER(cpu_unplug_list);
> > +
> > static XICSState *try_create_xics(const char *type, int nr_servers,
> > int nr_irqs, Error **errp)
> > {
> > @@ -2432,11 +2435,121 @@ 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_core_cleanup(void)
> > +{
> > + sPAPRCPUUnplug *unplug, *next;
> > + Object *cpu;
> > +
> > + QLIST_FOREACH_SAFE(unplug, &cpu_unplug_list, node, next) {
> > + cpu = unplug->cpu;
> > + object_unparent(cpu);
> > + QLIST_REMOVE(unplug, node);
> > + g_free(unplug);
> > + }
> > +}
> > +
> > +static void spapr_add_cpu_to_unplug_list(Object *cpu)
> > +{
> > + sPAPRCPUUnplug *unplug = g_malloc(sizeof(*unplug));
> > +
> > + unplug->cpu = cpu;
> > + QLIST_INSERT_HEAD(&cpu_unplug_list, unplug, node);
> > +}
> > +
> > +static int spapr_cpu_release(Object *obj, void *opaque)
> > +{
> > + DeviceState *dev = DEVICE(obj);
> > + CPUState *cs = CPU(dev);
> > + PowerPCCPU *cpu = POWERPC_CPU(cs);
> > +
> > + spapr_cpu_destroy(cpu);
> > + cpu_remove_sync(cs);
> > +
> > + /*
> > + * We are still walking the core object's children list, and
> > + * hence can't cleanup this CPU thread object just yet. Put
> > + * it on a list for later removal.
> > + */
> > + spapr_add_cpu_to_unplug_list(obj);
> > + return 0;
> > +}
> > +
> > +static void spapr_core_release(DeviceState *dev, void *opaque)
> > +{
> > + object_child_foreach(OBJECT(dev), spapr_cpu_release, opaque);
> > + spapr_cpu_core_cleanup();
> > + object_unparent(OBJECT(dev));
>
> I'd prefer to see the unplug_list as a local to this function (passed
> to spapr_cpu_release via opaque) rather than using a new global.
Will try that in the next iteration.
>
> > +}
> > +
> > +static int spapr_core_detach(Object *obj, void *opaque)
> > +{
> > + sPAPRCoreState *core = opaque;
> > + DeviceState *dev = DEVICE(obj);
> > + 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 (thread 0) will
> > + * continue and signal hot unplug event to the guest.
> > + */
>
> This seems silly. spapr_core_unplug() iterates through all the
> children only to have all of them except thread 0 ignore the call..
>
> Can't you just grab the first thread and do this logic directly from
> spapr_core_unplug()?
If I purely rely on the children list of the core object like I am doing
here, I don't see how to grab the first thread object from the list w/o
doing what I am doing here. However I can store the first thread object
in the core object during the core object's instance_init and use it here.
Will give it a try in the next iteration.
Regards,
Bharata.
[Qemu-devel] [PATCH v6 07/11] xics, xics_kvm: Handle CPU unplug correctly, Bharata B Rao, 2016/01/08
[Qemu-devel] [PATCH v6 08/11] target-ppc: Introduce PowerPC specific CPU core device, Bharata B Rao, 2016/01/08
[Qemu-devel] [PATCH v6 03/11] exec: Do vmstate unregistration from cpu_exec_exit(), Bharata B Rao, 2016/01/08