From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46857) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aZLKq-0006XB-6I for qemu-devel@nongnu.org; Fri, 26 Feb 2016 11:33:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aZLKl-0002Ka-5V for qemu-devel@nongnu.org; Fri, 26 Feb 2016 11:33:44 -0500 References: <1456417362-20652-1-git-send-email-bharata@linux.vnet.ibm.com> <1456417362-20652-6-git-send-email-bharata@linux.vnet.ibm.com> From: Thomas Huth Message-ID: <56D07E59.5000506@redhat.com> Date: Fri, 26 Feb 2016 17:33:29 +0100 MIME-Version: 1.0 In-Reply-To: <1456417362-20652-6-git-send-email-bharata@linux.vnet.ibm.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC PATCH v0 5/6] qmp, spapr: Show hot-plugged/pluggable CPU slots in the Machine List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Bharata B Rao , qemu-devel@nongnu.org Cc: mjrosato@linux.vnet.ibm.com, pkrempa@redhat.com, ehabkost@redhat.com, aik@ozlabs.ru, armbru@redhat.com, agraf@suse.de, borntraeger@de.ibm.com, qemu-ppc@nongnu.org, pbonzini@redhat.com, imammedo@redhat.com, mdroth@linux.vnet.ibm.com, afaerber@suse.de, david@gibson.dropbear.id.au On 25.02.2016 17:22, Bharata B Rao wrote: > Implement query cpu-slots that provides information about hot-plugged > as well as hot-pluggable CPU slots that the machine supports. >=20 > TODO: As Eric suggested use enum for type instead of str. > TODO: @hotplug-granularity probably isn't required. >=20 > Signed-off-by: Bharata B Rao > --- > hw/core/machine.c | 19 +++++++++ > hw/ppc/spapr.c | 112 ++++++++++++++++++++++++++++++++++++++++++++= ++++++++ > include/hw/boards.h | 4 ++ > qapi-schema.json | 85 +++++++++++++++++++++++++++++++++++++++ > qmp-commands.hx | 47 ++++++++++++++++++++++ > 5 files changed, 267 insertions(+) >=20 > diff --git a/hw/core/machine.c b/hw/core/machine.c > index 6d1a0d8..3055ef8 100644 > --- a/hw/core/machine.c > +++ b/hw/core/machine.c > @@ -17,6 +17,25 @@ > #include "hw/sysbus.h" > #include "sysemu/sysemu.h" > #include "qemu/error-report.h" > +#include "qmp-commands.h" > + > +/* > + * QMP: query-cpu-slots > + * > + * TODO: Ascertain if this is the right place to for this arch-neutral= routine. > + */ > +CPUSlotInfoList *qmp_query_cpu_slots(Error **errp) > +{ > + MachineState *ms =3D MACHINE(qdev_get_machine()); > + MachineClass *mc =3D MACHINE_GET_CLASS(ms); > + > + if (!mc->cpu_slots) { > + error_setg(errp, QERR_UNSUPPORTED); > + return NULL; > + } > + > + return mc->cpu_slots(ms); > +} > =20 > static char *machine_get_accel(Object *obj, Error **errp) > { > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 780cd00..b76ed85 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -2453,6 +2453,117 @@ static unsigned spapr_cpu_index_to_socket_id(un= signed cpu_index) > return cpu_index / smp_threads / smp_cores; > } > =20 > +static int spapr_cpuinfo_list(Object *obj, void *opaque) > +{ > + MachineClass *mc =3D MACHINE_GET_CLASS(qdev_get_machine()); > + CPUInfoList ***prev =3D opaque; > + > + if (object_dynamic_cast(obj, TYPE_CPU)) { > + CPUInfoList *elem =3D g_new0(CPUInfoList, 1); > + CPUInfo *s =3D g_new0(CPUInfo, 1); > + CPUState *cpu =3D CPU(obj); > + PowerPCCPU *pcpu =3D POWERPC_CPU(cpu); > + > + s->arch_id =3D ppc_get_vcpu_dt_id(pcpu); > + s->type =3D g_strdup(object_get_typename(obj)); > + s->thread =3D cpu->cpu_index; > + s->has_thread =3D true; > + s->core =3D cpu->cpu_index / smp_threads; > + s->has_core =3D true; > + if (mc->cpu_index_to_socket_id) { > + s->socket =3D mc->cpu_index_to_socket_id(cpu->cpu_index); > + } else { > + s->socket =3D cpu->cpu_index / smp_threads / smp_cores; > + } > + s->has_socket =3D true; > + s->node =3D cpu->numa_node; > + s->has_node =3D true; > + s->qom_path =3D object_get_canonical_path(obj); > + s->has_qom_path =3D true; > + > + elem->value =3D s; > + elem->next =3D NULL; > + **prev =3D elem; > + *prev =3D &elem->next; > + } > + object_child_foreach(obj, spapr_cpuinfo_list, opaque); > + return 0; > +} > + > +static CPUSlotInfoList *spapr_cpu_slots(MachineState *machine) > +{ > + CPUSlotInfoList *head =3D NULL; > + CPUSlotInfoList **prev =3D &head; > + Object *root_container; > + ObjectProperty *prop; > + ObjectPropertyIterator iter; > + > + /* > + * TODO: There surely must be a better/easier way to walk all > + * the link properties of an object ? > + */ > + root_container =3D container_get(object_get_root(), "/machine"); > + object_property_iter_init(&iter, root_container); > + > + while ((prop =3D object_property_iter_next(&iter))) { > + Object *obj; > + DeviceState *dev; > + CPUSlotInfoList *elem; > + CPUSlotInfo *s; > + CPUInfoList *cpu_head =3D NULL; > + CPUInfoList **cpu_prev =3D &cpu_head; > + sPAPRCPUCore *core; > + > + if (!strstart(prop->type, "link<", NULL)) { > + continue; > + } > + > + if (!strstart(prop->name, SPAPR_MACHINE_CPU_CORE_PROP, NULL)) = { > + continue; > + } > + > + elem =3D g_new0(CPUSlotInfoList, 1); > + s =3D g_new0(CPUSlotInfo, 1); > + > + obj =3D object_property_get_link(root_container, prop->name, N= ULL); > + if (obj) { > + /* Slot populated */ > + dev =3D DEVICE(obj); > + core =3D SPAPR_CPU_CORE(obj); > + > + if (dev->id) { > + s->has_id =3D true; > + s->id =3D g_strdup(dev->id); > + } > + s->realized =3D object_property_get_bool(obj, "realized", = NULL); > + s->nr_cpus =3D core->nr_threads; > + s->has_nr_cpus =3D true; > + s->qom_path =3D object_get_canonical_path(obj); > + s->has_qom_path =3D true; > + if (s->realized) { > + spapr_cpuinfo_list(obj, &cpu_prev); > + } > + s->has_cpus =3D true; > + } else { > + /* Slot empty */ > + s->has_id =3D false; > + s->has_nr_cpus =3D false; > + s->has_qom_path =3D false; > + s->has_cpus =3D false; > + s->realized =3D false; > + } I think you could drop that whole else-path since you've already used g_new0 to make sure that the memory of the new CPUSlotInfo is cleared. > + s->type =3D g_strdup(TYPE_SPAPR_CPU_CORE); > + s->hotplug_granularity =3D g_strdup(SPAPR_MACHINE_CPU_CORE_PRO= P); > + s->slot_id =3D g_strdup(prop->name); > + s->cpus =3D cpu_head; > + elem->value =3D s; > + elem->next =3D NULL; > + *prev =3D elem; > + prev =3D &elem->next; > + } > + return head; > +} Thomas