From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37584) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1amxfQ-0001iK-JW for qemu-devel@nongnu.org; Mon, 04 Apr 2016 02:07:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1amxfN-0000ZR-C3 for qemu-devel@nongnu.org; Mon, 04 Apr 2016 02:07:16 -0400 Date: Mon, 4 Apr 2016 14:27:24 +1000 From: David Gibson Message-ID: <20160404042724.GK16485@voom.fritz.box> References: <1459413561-30745-1-git-send-email-bharata@linux.vnet.ibm.com> <1459413561-30745-13-git-send-email-bharata@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="Rex5+51txc1ort/q" Content-Disposition: inline In-Reply-To: <1459413561-30745-13-git-send-email-bharata@linux.vnet.ibm.com> Subject: Re: [Qemu-devel] [RFC PATCH v2.1 12/12] spapr: CPU hot unplug support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Bharata B Rao Cc: mjrosato@linux.vnet.ibm.com, agraf@suse.de, thuth@redhat.com, pkrempa@redhat.com, ehabkost@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, armbru@redhat.com, borntraeger@de.ibm.com, qemu-ppc@nongnu.org, pbonzini@redhat.com, imammedo@redhat.com, afaerber@suse.de, mdroth@linux.vnet.ibm.com --Rex5+51txc1ort/q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Mar 31, 2016 at 02:09:21PM +0530, Bharata B Rao wrote: > Remove the CPU core device by removing the underlying CPU thread devices. > Hot removal of CPU for sPAPR guests is achieved by sending the hot unplug > notification to the guest. Release the vCPU object after CPU hot unplug so > that vCPU fd can be parked and reused. >=20 > Signed-off-by: Bharata B Rao > --- > hw/ppc/spapr.c | 16 ++++++++ > hw/ppc/spapr_cpu_core.c | 86 +++++++++++++++++++++++++++++++++++= ++++++ > include/hw/ppc/spapr.h | 1 + > include/hw/ppc/spapr_cpu_core.h | 11 ++++++ > 4 files changed, 114 insertions(+) >=20 > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 1a5dbd9..74cdcf2 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -2348,11 +2348,27 @@ static void spapr_machine_device_plug(HotplugHand= ler *hotplug_dev, > } > } > =20 > +void spapr_cpu_destroy(PowerPCCPU *cpu) > +{ > + sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); > + > + xics_cpu_destroy(spapr->icp, cpu); > + qemu_unregister_reset(spapr_cpu_reset, cpu); > +} > + > static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, > DeviceState *dev, Error **errp) > { > + sPAPRMachineClass *smc =3D 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_SPAPR_CPU_CORE)) { > + if (!smc->dr_cpu_enabled) { > + error_setg(errp, "CPU hot unplug not supported on this machi= ne"); > + return; > + } > + spapr_core_unplug(hotplug_dev, dev, errp); > } > } > =20 > diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c > index a9ba843..09a592e 100644 > --- a/hw/ppc/spapr_cpu_core.c > +++ b/hw/ppc/spapr_cpu_core.c > @@ -119,6 +119,92 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, De= viceState *dev, > } > } > =20 > +static void spapr_cpu_core_cleanup(struct sPAPRCPUUnplugList *unplug_lis= t) > +{ > + sPAPRCPUUnplug *unplug, *next; > + Object *cpu; > + > + QLIST_FOREACH_SAFE(unplug, unplug_list, node, next) { > + cpu =3D unplug->cpu; > + object_unparent(cpu); Is there any danger in the fact that the cpu object is still in the QOM tree until unparented here? My usual expectation would be that you'd remove the object from the tree immediately, but defer the actual free. But I'm a bit unclear on how QOM removals are supposed to work. > + QLIST_REMOVE(unplug, node); > + g_free(unplug); > + } > +} > + > +static void spapr_add_cpu_to_unplug_list(Object *cpu, > + struct sPAPRCPUUnplugList *unpl= ug_list) > +{ > + sPAPRCPUUnplug *unplug =3D g_malloc(sizeof(*unplug)); > + > + unplug->cpu =3D cpu; > + QLIST_INSERT_HEAD(unplug_list, unplug, node); > +} > + > +static int spapr_cpu_release(Object *obj, void *opaque) > +{ > + DeviceState *dev =3D DEVICE(obj); > + CPUState *cs =3D CPU(dev); > + PowerPCCPU *cpu =3D POWERPC_CPU(cs); > + struct sPAPRCPUUnplugList *unplug_list =3D opaque; > + > + 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, unplug_list); > + return 0; > +} > + > +static void spapr_core_release(DeviceState *dev) > +{ > + struct sPAPRCPUUnplugList unplug_list; > + sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); > + sPAPRCPUCore *core =3D SPAPR_CPU_CORE(OBJECT(dev)); > + CPUCore *cc =3D CPU_CORE(dev); > + int smt =3D kvmppc_smt_threads(); > + > + QLIST_INIT(&unplug_list); > + object_child_foreach(OBJECT(dev), spapr_cpu_release, &unplug_list); > + spapr_cpu_core_cleanup(&unplug_list); > + spapr->cores[cc->core / smt] =3D NULL; > + > + g_free(core->threads); > +} > + > +static void spapr_core_release_unparent(DeviceState *dev, void *opaque) > +{ > + spapr_core_release(dev); > + object_unparent(OBJECT(dev)); > +} > + > +void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, > + Error **errp) > +{ > + sPAPRCPUCore *core =3D SPAPR_CPU_CORE(OBJECT(dev)); > + PowerPCCPU *cpu =3D &core->threads[0]; > + int id =3D ppc_get_vcpu_dt_id(cpu); > + sPAPRDRConnector *drc =3D > + spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id); > + sPAPRDRConnectorClass *drck; > + Error *local_err =3D NULL; > + > + g_assert(drc); > + > + drck =3D SPAPR_DR_CONNECTOR_GET_CLASS(drc); > + drck->detach(drc, dev, spapr_core_release_unparent, NULL, &local_err= ); > + if (local_err) { > + error_propagate(errp, local_err); > + return; > + } > + > + spapr_hotplug_req_remove_by_index(drc); > +} > + > static const TypeInfo spapr_cpu_core_type_info =3D { > .name =3D TYPE_SPAPR_CPU_CORE, > .parent =3D TYPE_CPU_CORE, > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 619db98..c5a4a15 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -590,6 +590,7 @@ void spapr_hotplug_req_remove_by_count(sPAPRDRConnect= orType drc_type, > void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **e= rrp); > void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, > sPAPRMachineState *spapr); > +void spapr_cpu_destroy(PowerPCCPU *cpu); > =20 > /* rtas-configure-connector state */ > struct sPAPRConfigureConnectorState { > diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_c= ore.h > index 165af7c..9bc2e01 100644 > --- a/include/hw/ppc/spapr_cpu_core.h > +++ b/include/hw/ppc/spapr_cpu_core.h > @@ -65,4 +65,15 @@ void spapr_core_pre_plug(HotplugHandler *hotplug_dev, = DeviceState *dev, > char *spapr_get_cpu_core_type(const char *model); > void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, > Error **errp); > +void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, > + Error **errp); > + > +/* List to store unplugged CPU objects for cleanup during unplug */ > +typedef struct sPAPRCPUUnplug { > + Object *cpu; > + QLIST_ENTRY(sPAPRCPUUnplug) node; > +} sPAPRCPUUnplug; > + > +QLIST_HEAD(sPAPRCPUUnplugList, sPAPRCPUUnplug); > + > #endif --=20 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 --Rex5+51txc1ort/q Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJXAe0sAAoJEGw4ysog2bOS75sQAMao2KSkIjYQ/g9zwfe/iz2/ 7hrFRCM5t2MqYChMsd5sU28MB1UqTV7xqisPXruz0F0bOpccdW6woGGS/htAEiuN tly22GYotcfgOg1dj4+J2nwxG45DpvamGQ4Pn0Yev6JFjaPorb2qXDdxSkqQMoT/ E1x0Gv22JsmwdyKd2OCxOs1MdCXuVSmPj3AZp9htrCHiimMUgB3ruk0jVpP/ins2 a9CszLOpNFVpPNUxFGidhSCFxPkOsn42LHzrXarJspOYRar/HZ0c7k2stNOqFL02 kLIcwPICvB8Bkfx26Wr1CiQzA0qM0M8RNTiSj5KOIna9QICsYKzwzQ1OXO0dQpt/ O26H+doDsMWsZyK2DushFS5dhfGYBCNBimVK2JoLVT0TYKt9B3z8BUPd+WwQS8wf 27ylI1K8Chj5GdirBEYoGhQcOOcGoWwJxrL42Ay2wY29XSX02gN3LQ0OMC/zw417 vgty2enGCTr5XMeB0RdURPCj2yPw1nlAtQ76RhYo3kOLZkFUHFAJnSUBx19Q1kqA t+okxT4bINmOf8oPfSFIlcf2436n7QWdMerE7h3Lds7HgzKB0Nmzwt2uZxvdGvgv Zxxmy4/e/HovuJ4H0SIeZRNuhzuWKJcD5R3Sp0MzKyANsh6bvqOT10Q8a7XRStdz HdsEj1nrIdrDR6aU4ehg =uWe1 -----END PGP SIGNATURE----- --Rex5+51txc1ort/q--