Message ID | 1484759609-264075-9-git-send-email-imammedo@redhat.com |
---|---|
State | New |
Headers | show |
On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > it will allow generic numa code to set cpu to numa node mapping > in target independent manner in the next patch. > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> This looks like a creative way to abuse the QOM property system. What's the problem with using a simple C function like: void (*set_cpu_affinity)(MachineState *m, CpuInstanceProperties *props, Error **errp) ? > --- > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 56 insertions(+) > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > index f8ea635..1d33a5e 100644 > --- a/hw/i386/pc.c > +++ b/hw/i386/pc.c > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > pcms->pit = value; > } > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + uint32_t apic_id; > + X86CPUTopoInfo topo; > + CPUArchId *cpu_slot; > + Error *local_err = NULL; > + CpuInstanceProperties *cpu_props = NULL; > + PCMachineState *pcms = PC_MACHINE(obj); > + MachineClass *mc = MACHINE_GET_CLASS(obj); > + > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > + if (local_err) { > + goto out; > + } > + > + if (!cpu_props->has_node_id) { > + error_setg(&local_err, "node-id property is not specified"); > + goto out; > + } > + > + /* > + * make sure that possible_cpus is initialized > + * as property setter might be called before machine init is called > + */ > + mc->possible_cpu_arch_ids(MACHINE(obj)); > + > + topo.pkg_id = cpu_props->socket_id; > + topo.core_id = cpu_props->core_id; > + topo.smt_id = cpu_props->thread_id; > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); > + if (!cpu_slot) { > + error_setg(&local_err, "unable to find CPU"); > + goto out; > + } > + > + if (cpu_slot->props.has_node_id) { > + error_setg(&local_err, "CPU has already been assigned to node: %"PRId64, > + cpu_slot->props.node_id); > + goto out; > + } > + cpu_slot->props.has_node_id = true; > + cpu_slot->props.node_id = cpu_props->node_id; > + > + out: > + error_propagate(errp, local_err); > + qapi_free_CpuInstanceProperties(cpu_props); > +} > + > static void pc_machine_initfn(Object *obj) > { > PCMachineState *pcms = PC_MACHINE(obj); > @@ -2395,6 +2445,12 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) > > object_class_property_add_bool(oc, PC_MACHINE_PIT, > pc_machine_get_pit, pc_machine_set_pit, &error_abort); > + > + object_class_property_add(oc, "cpu", "CpuInstanceProperties", > + NULL, pc_machine_set_cpu, > + NULL, NULL, &error_abort); > + object_class_property_set_description(oc, "cpu", > + "Possible cpu placement", &error_abort); > } > > static const TypeInfo pc_machine_info = { > -- > 2.7.4 >
On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > it will allow generic numa code to set cpu to numa node mapping > in target independent manner in the next patch. > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > --- > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 56 insertions(+) > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > index f8ea635..1d33a5e 100644 > --- a/hw/i386/pc.c > +++ b/hw/i386/pc.c > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > pcms->pit = value; > } > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + uint32_t apic_id; > + X86CPUTopoInfo topo; > + CPUArchId *cpu_slot; > + Error *local_err = NULL; > + CpuInstanceProperties *cpu_props = NULL; > + PCMachineState *pcms = PC_MACHINE(obj); > + MachineClass *mc = MACHINE_GET_CLASS(obj); > + > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > + if (local_err) { > + goto out; > + } > + > + if (!cpu_props->has_node_id) { > + error_setg(&local_err, "node-id property is not specified"); > + goto out; > + } > + > + /* > + * make sure that possible_cpus is initialized > + * as property setter might be called before machine init is called > + */ > + mc->possible_cpu_arch_ids(MACHINE(obj)); > + > + topo.pkg_id = cpu_props->socket_id; > + topo.core_id = cpu_props->core_id; > + topo.smt_id = cpu_props->thread_id; > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); If we make TYPE_MACHINE provide an API to query CPU slots, e.g.: CPUArchId *machine_find_cpu_slot(MachineState *m, CpuInstanceProperties *props) CPUArchId *machine_slot_for_cpu(MachineState *m, CPUState *cpu) (Which can probably be implemented using MachineClass::possible_cpu_arch_ids(), already) Then this function could be implemented in a generic way, and all existing calls of: numa_get_node_for_cpu(cpu->cpu_index) could be easily replaced by: machine_slot_for_cpu(cpu)->props.node_id This should make it easier to get rid numa_info[].node_cpu. > + if (!cpu_slot) { > + error_setg(&local_err, "unable to find CPU"); > + goto out; > + } > + > + if (cpu_slot->props.has_node_id) { > + error_setg(&local_err, "CPU has already been assigned to node: %"PRId64, > + cpu_slot->props.node_id); > + goto out; > + } > + cpu_slot->props.has_node_id = true; > + cpu_slot->props.node_id = cpu_props->node_id; > + > + out: > + error_propagate(errp, local_err); > + qapi_free_CpuInstanceProperties(cpu_props); > +} > + > static void pc_machine_initfn(Object *obj) > { > PCMachineState *pcms = PC_MACHINE(obj); > @@ -2395,6 +2445,12 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) > > object_class_property_add_bool(oc, PC_MACHINE_PIT, > pc_machine_get_pit, pc_machine_set_pit, &error_abort); > + > + object_class_property_add(oc, "cpu", "CpuInstanceProperties", > + NULL, pc_machine_set_cpu, > + NULL, NULL, &error_abort); > + object_class_property_set_description(oc, "cpu", > + "Possible cpu placement", &error_abort); > } > > static const TypeInfo pc_machine_info = { > -- > 2.7.4 >
On Wed, 18 Jan 2017 16:27:21 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > > it will allow generic numa code to set cpu to numa node mapping > > in target independent manner in the next patch. > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > This looks like a creative way to abuse the QOM property system. > What's the problem with using a simple C function like: > void (*set_cpu_affinity)(MachineState *m, CpuInstanceProperties *props, Error **errp) Agreed, it should simplify parsing code as well. > ? > > > > --- > > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 56 insertions(+) > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > > index f8ea635..1d33a5e 100644 > > --- a/hw/i386/pc.c > > +++ b/hw/i386/pc.c > > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > > pcms->pit = value; > > } > > > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + uint32_t apic_id; > > + X86CPUTopoInfo topo; > > + CPUArchId *cpu_slot; > > + Error *local_err = NULL; > > + CpuInstanceProperties *cpu_props = NULL; > > + PCMachineState *pcms = PC_MACHINE(obj); > > + MachineClass *mc = MACHINE_GET_CLASS(obj); > > + > > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > > + if (local_err) { > > + goto out; > > + } > > + > > + if (!cpu_props->has_node_id) { > > + error_setg(&local_err, "node-id property is not specified"); > > + goto out; > > + } > > + > > + /* > > + * make sure that possible_cpus is initialized > > + * as property setter might be called before machine init is called > > + */ > > + mc->possible_cpu_arch_ids(MACHINE(obj)); > > + > > + topo.pkg_id = cpu_props->socket_id; > > + topo.core_id = cpu_props->core_id; > > + topo.smt_id = cpu_props->thread_id; > > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); > > + if (!cpu_slot) { > > + error_setg(&local_err, "unable to find CPU"); > > + goto out; > > + } > > + > > + if (cpu_slot->props.has_node_id) { > > + error_setg(&local_err, "CPU has already been assigned to node: %"PRId64, > > + cpu_slot->props.node_id); > > + goto out; > > + } > > + cpu_slot->props.has_node_id = true; > > + cpu_slot->props.node_id = cpu_props->node_id; > > + > > + out: > > + error_propagate(errp, local_err); > > + qapi_free_CpuInstanceProperties(cpu_props); > > +} > > + > > static void pc_machine_initfn(Object *obj) > > { > > PCMachineState *pcms = PC_MACHINE(obj); > > @@ -2395,6 +2445,12 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) > > > > object_class_property_add_bool(oc, PC_MACHINE_PIT, > > pc_machine_get_pit, pc_machine_set_pit, &error_abort); > > + > > + object_class_property_add(oc, "cpu", "CpuInstanceProperties", > > + NULL, pc_machine_set_cpu, > > + NULL, NULL, &error_abort); > > + object_class_property_set_description(oc, "cpu", > > + "Possible cpu placement", &error_abort); > > } > > > > static const TypeInfo pc_machine_info = { > > -- > > 2.7.4 > > >
On Wed, 18 Jan 2017 16:57:13 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > > it will allow generic numa code to set cpu to numa node mapping > > in target independent manner in the next patch. > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > --- > > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 56 insertions(+) > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > > index f8ea635..1d33a5e 100644 > > --- a/hw/i386/pc.c > > +++ b/hw/i386/pc.c > > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > > pcms->pit = value; > > } > > > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + uint32_t apic_id; > > + X86CPUTopoInfo topo; > > + CPUArchId *cpu_slot; > > + Error *local_err = NULL; > > + CpuInstanceProperties *cpu_props = NULL; > > + PCMachineState *pcms = PC_MACHINE(obj); > > + MachineClass *mc = MACHINE_GET_CLASS(obj); > > + > > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > > + if (local_err) { > > + goto out; > > + } > > + > > + if (!cpu_props->has_node_id) { > > + error_setg(&local_err, "node-id property is not specified"); > > + goto out; > > + } > > + > > + /* > > + * make sure that possible_cpus is initialized > > + * as property setter might be called before machine init is called > > + */ > > + mc->possible_cpu_arch_ids(MACHINE(obj)); > > + > > + topo.pkg_id = cpu_props->socket_id; > > + topo.core_id = cpu_props->core_id; > > + topo.smt_id = cpu_props->thread_id; > > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); > > If we make TYPE_MACHINE provide an API to query CPU slots, e.g.: > CPUArchId *machine_find_cpu_slot(MachineState *m, CpuInstanceProperties *props) so if there is no objections, I'll move possible_cpus to MachineState and add to MachineClass above callback so target machine would be able to provide arch specific lookup function. it should work for both x86 and ARM. > CPUArchId *machine_slot_for_cpu(MachineState *m, CPUState *cpu) probably won't work for SPAPR where they have cores, machine_find_cpu_slot() alone might be sufficient. > (Which can probably be implemented using > MachineClass::possible_cpu_arch_ids(), already) > > Then this function could be implemented in a generic way, and all > existing calls of: > numa_get_node_for_cpu(cpu->cpu_index) > could be easily replaced by: > machine_slot_for_cpu(cpu)->props.node_id most of such places could be replaced directly by plain cpu->node_id > > This should make it easier to get rid numa_info[].node_cpu. PS: Adding Bharata to CC so SPAPR side could voice their opinion. > > + if (!cpu_slot) { > > + error_setg(&local_err, "unable to find CPU"); > > + goto out; > > + } > > + > > + if (cpu_slot->props.has_node_id) { > > + error_setg(&local_err, "CPU has already been assigned to node: %"PRId64, > > + cpu_slot->props.node_id); > > + goto out; > > + } > > + cpu_slot->props.has_node_id = true; > > + cpu_slot->props.node_id = cpu_props->node_id; > > + > > + out: > > + error_propagate(errp, local_err); > > + qapi_free_CpuInstanceProperties(cpu_props); > > +} > > + > > static void pc_machine_initfn(Object *obj) > > { > > PCMachineState *pcms = PC_MACHINE(obj); > > @@ -2395,6 +2445,12 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) > > > > object_class_property_add_bool(oc, PC_MACHINE_PIT, > > pc_machine_get_pit, pc_machine_set_pit, &error_abort); > > + > > + object_class_property_add(oc, "cpu", "CpuInstanceProperties", > > + NULL, pc_machine_set_cpu, > > + NULL, NULL, &error_abort); > > + object_class_property_set_description(oc, "cpu", > > + "Possible cpu placement", &error_abort); > > } > > > > static const TypeInfo pc_machine_info = { > > -- > > 2.7.4 > > >
On Thu, Jan 19, 2017 at 04:04:23PM +0100, Igor Mammedov wrote: > On Wed, 18 Jan 2017 16:57:13 -0200 > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > > > it will allow generic numa code to set cpu to numa node mapping > > > in target independent manner in the next patch. > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > > --- > > > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > 1 file changed, 56 insertions(+) > > > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > > > index f8ea635..1d33a5e 100644 > > > --- a/hw/i386/pc.c > > > +++ b/hw/i386/pc.c > > > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > > > pcms->pit = value; > > > } > > > > > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > > > + void *opaque, Error **errp) > > > +{ > > > + uint32_t apic_id; > > > + X86CPUTopoInfo topo; > > > + CPUArchId *cpu_slot; > > > + Error *local_err = NULL; > > > + CpuInstanceProperties *cpu_props = NULL; > > > + PCMachineState *pcms = PC_MACHINE(obj); > > > + MachineClass *mc = MACHINE_GET_CLASS(obj); > > > + > > > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > > > + if (local_err) { > > > + goto out; > > > + } > > > + > > > + if (!cpu_props->has_node_id) { > > > + error_setg(&local_err, "node-id property is not specified"); > > > + goto out; > > > + } > > > + > > > + /* > > > + * make sure that possible_cpus is initialized > > > + * as property setter might be called before machine init is called > > > + */ > > > + mc->possible_cpu_arch_ids(MACHINE(obj)); > > > + > > > + topo.pkg_id = cpu_props->socket_id; > > > + topo.core_id = cpu_props->core_id; > > > + topo.smt_id = cpu_props->thread_id; > > > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > > > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); > > > > If we make TYPE_MACHINE provide an API to query CPU slots, e.g.: > > CPUArchId *machine_find_cpu_slot(MachineState *m, CpuInstanceProperties *props) > so if there is no objections, > I'll move possible_cpus to MachineState > and add to MachineClass above callback so target machine > would be able to provide arch specific lookup function. > it should work for both x86 and ARM. The need for possible_cpus in MachineState for sPAPR isn't immediately apparent to me. In the context of this new numa "cpu" property, PC target seems to use possible_cpus to store and later lookup the numa node id for a given CPU. Wondering if that could be achieved w/o needing possible_cpus in MachineState ? Regards, Bharata.
On Mon, Jan 23, 2017 at 12:20:33PM +0530, Bharata B Rao wrote: > On Thu, Jan 19, 2017 at 04:04:23PM +0100, Igor Mammedov wrote: > > On Wed, 18 Jan 2017 16:57:13 -0200 > > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > > > On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > > > > it will allow generic numa code to set cpu to numa node mapping > > > > in target independent manner in the next patch. > > > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > > > --- > > > > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > > 1 file changed, 56 insertions(+) > > > > > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > > > > index f8ea635..1d33a5e 100644 > > > > --- a/hw/i386/pc.c > > > > +++ b/hw/i386/pc.c > > > > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > > > > pcms->pit = value; > > > > } > > > > > > > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > > > > + void *opaque, Error **errp) > > > > +{ > > > > + uint32_t apic_id; > > > > + X86CPUTopoInfo topo; > > > > + CPUArchId *cpu_slot; > > > > + Error *local_err = NULL; > > > > + CpuInstanceProperties *cpu_props = NULL; > > > > + PCMachineState *pcms = PC_MACHINE(obj); > > > > + MachineClass *mc = MACHINE_GET_CLASS(obj); > > > > + > > > > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > > > > + if (local_err) { > > > > + goto out; > > > > + } > > > > + > > > > + if (!cpu_props->has_node_id) { > > > > + error_setg(&local_err, "node-id property is not specified"); > > > > + goto out; > > > > + } > > > > + > > > > + /* > > > > + * make sure that possible_cpus is initialized > > > > + * as property setter might be called before machine init is called > > > > + */ > > > > + mc->possible_cpu_arch_ids(MACHINE(obj)); > > > > + > > > > + topo.pkg_id = cpu_props->socket_id; > > > > + topo.core_id = cpu_props->core_id; > > > > + topo.smt_id = cpu_props->thread_id; > > > > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > > > > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); > > > > > > If we make TYPE_MACHINE provide an API to query CPU slots, e.g.: > > > CPUArchId *machine_find_cpu_slot(MachineState *m, CpuInstanceProperties *props) > > so if there is no objections, > > I'll move possible_cpus to MachineState > > and add to MachineClass above callback so target machine > > would be able to provide arch specific lookup function. > > it should work for both x86 and ARM. > > The need for possible_cpus in MachineState for sPAPR isn't immediately > apparent to me. In the context of this new numa "cpu" property, PC target > seems to use possible_cpus to store and later lookup the numa node id for > a given CPU. Wondering if that could be achieved w/o needing possible_cpus > in MachineState ? We need to save the node ID for not-yet-plugged CPUs somewhere, and the existing numa_info[].node_cpu field is cpu_index-based so it needs to be replaced. A MachineState field would allow us to do that in a generic way.
On Mon, 23 Jan 2017 13:03:50 -0200 Eduardo Habkost <ehabkost@redhat.com> wrote: > On Mon, Jan 23, 2017 at 12:20:33PM +0530, Bharata B Rao wrote: > > On Thu, Jan 19, 2017 at 04:04:23PM +0100, Igor Mammedov wrote: > > > On Wed, 18 Jan 2017 16:57:13 -0200 > > > Eduardo Habkost <ehabkost@redhat.com> wrote: > > > > > > > On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote: > > > > > it will allow generic numa code to set cpu to numa node mapping > > > > > in target independent manner in the next patch. > > > > > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > > > > --- > > > > > hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > > > 1 file changed, 56 insertions(+) > > > > > > > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > > > > > index f8ea635..1d33a5e 100644 > > > > > --- a/hw/i386/pc.c > > > > > +++ b/hw/i386/pc.c > > > > > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) > > > > > pcms->pit = value; > > > > > } > > > > > > > > > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, > > > > > + void *opaque, Error **errp) > > > > > +{ > > > > > + uint32_t apic_id; > > > > > + X86CPUTopoInfo topo; > > > > > + CPUArchId *cpu_slot; > > > > > + Error *local_err = NULL; > > > > > + CpuInstanceProperties *cpu_props = NULL; > > > > > + PCMachineState *pcms = PC_MACHINE(obj); > > > > > + MachineClass *mc = MACHINE_GET_CLASS(obj); > > > > > + > > > > > + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); > > > > > + if (local_err) { > > > > > + goto out; > > > > > + } > > > > > + > > > > > + if (!cpu_props->has_node_id) { > > > > > + error_setg(&local_err, "node-id property is not specified"); > > > > > + goto out; > > > > > + } > > > > > + > > > > > + /* > > > > > + * make sure that possible_cpus is initialized > > > > > + * as property setter might be called before machine init is called > > > > > + */ > > > > > + mc->possible_cpu_arch_ids(MACHINE(obj)); > > > > > + > > > > > + topo.pkg_id = cpu_props->socket_id; > > > > > + topo.core_id = cpu_props->core_id; > > > > > + topo.smt_id = cpu_props->thread_id; > > > > > + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); > > > > > + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); > > > > > > > > If we make TYPE_MACHINE provide an API to query CPU slots, e.g.: > > > > CPUArchId *machine_find_cpu_slot(MachineState *m, CpuInstanceProperties *props) > > > so if there is no objections, > > > I'll move possible_cpus to MachineState > > > and add to MachineClass above callback so target machine > > > would be able to provide arch specific lookup function. > > > it should work for both x86 and ARM. > > > > The need for possible_cpus in MachineState for sPAPR isn't immediately > > apparent to me. In the context of this new numa "cpu" property, PC target > > seems to use possible_cpus to store and later lookup the numa node id for > > a given CPU. Wondering if that could be achieved w/o needing possible_cpus > > in MachineState ? > > We need to save the node ID for not-yet-plugged CPUs somewhere, > and the existing numa_info[].node_cpu field is cpu_index-based so > it needs to be replaced. A MachineState field would allow us to > do that in a generic way. I'm trying to quickly hack SPAPR code to use possible_cpus to show how it would be used. But using the same possible_cpus across targets have as minimum a benefit of uniform approach and possibly more code sharing.
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f8ea635..1d33a5e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) pcms->pit = value; } +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint32_t apic_id; + X86CPUTopoInfo topo; + CPUArchId *cpu_slot; + Error *local_err = NULL; + CpuInstanceProperties *cpu_props = NULL; + PCMachineState *pcms = PC_MACHINE(obj); + MachineClass *mc = MACHINE_GET_CLASS(obj); + + visit_type_CpuInstanceProperties(v, name, &cpu_props, &local_err); + if (local_err) { + goto out; + } + + if (!cpu_props->has_node_id) { + error_setg(&local_err, "node-id property is not specified"); + goto out; + } + + /* + * make sure that possible_cpus is initialized + * as property setter might be called before machine init is called + */ + mc->possible_cpu_arch_ids(MACHINE(obj)); + + topo.pkg_id = cpu_props->socket_id; + topo.core_id = cpu_props->core_id; + topo.smt_id = cpu_props->thread_id; + apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo); + cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL); + if (!cpu_slot) { + error_setg(&local_err, "unable to find CPU"); + goto out; + } + + if (cpu_slot->props.has_node_id) { + error_setg(&local_err, "CPU has already been assigned to node: %"PRId64, + cpu_slot->props.node_id); + goto out; + } + cpu_slot->props.has_node_id = true; + cpu_slot->props.node_id = cpu_props->node_id; + + out: + error_propagate(errp, local_err); + qapi_free_CpuInstanceProperties(cpu_props); +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -2395,6 +2445,12 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) object_class_property_add_bool(oc, PC_MACHINE_PIT, pc_machine_get_pit, pc_machine_set_pit, &error_abort); + + object_class_property_add(oc, "cpu", "CpuInstanceProperties", + NULL, pc_machine_set_cpu, + NULL, NULL, &error_abort); + object_class_property_set_description(oc, "cpu", + "Possible cpu placement", &error_abort); } static const TypeInfo pc_machine_info = {
it will allow generic numa code to set cpu to numa node mapping in target independent manner in the next patch. Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- hw/i386/pc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)