From: Pierre Morel <pmorel@linux.ibm.com> To: qemu-s390x@nongnu.org Cc: qemu-devel@nongnu.org, borntraeger@de.ibm.com, pasic@linux.ibm.com, richard.henderson@linaro.org, david@redhat.com, thuth@redhat.com, cohuck@redhat.com, mst@redhat.com, pbonzini@redhat.com, kvm@vger.kernel.org, ehabkost@redhat.com, marcel.apfelbaum@gmail.com, philmd@redhat.com, eblake@redhat.com, armbru@redhat.com Subject: [PATCH v5 11/12] s390x: topology: implementing numa for the s390x topology Date: Thu, 9 Dec 2021 14:46:42 +0100 [thread overview] Message-ID: <20211209134643.143866-12-pmorel@linux.ibm.com> (raw) In-Reply-To: <20211209134643.143866-1-pmorel@linux.ibm.com> S390x CPU Topology allows a non uniform repartition of the CPU inside the topology containers, sockets, books and drawers. We use numa to place the CPU inside the right topology container and report the non uniform topology to the guest. Note that s390x needs CPU0 to belong to the topology and consequently all topology must include CPU0. We accept a partial QEMU numa definition, in that case undefined CPUs are added to free slots in the topology starting with slot 0 and going up. Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> --- hw/core/machine.c | 18 ++++++++++ hw/s390x/s390-virtio-ccw.c | 68 ++++++++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 0059070309..d65a91c607 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -684,6 +684,16 @@ void machine_set_cpu_numa_node(MachineState *machine, return; } + if (props->has_book_id && !slot->props.has_book_id) { + error_setg(errp, "book-id is not supported"); + return; + } + + if (props->has_drawer_id && !slot->props.has_drawer_id) { + error_setg(errp, "drawer-id is not supported"); + return; + } + /* skip slots with explicit mismatch */ if (props->has_thread_id && props->thread_id != slot->props.thread_id) { continue; @@ -701,6 +711,14 @@ void machine_set_cpu_numa_node(MachineState *machine, continue; } + if (props->has_book_id && props->book_id != slot->props.book_id) { + continue; + } + + if (props->has_drawer_id && props->drawer_id != slot->props.drawer_id) { + continue; + } + /* reject assignment if slot is already assigned, for compatibility * of legacy cpu_index mapping with SPAPR core based mapping do not * error out if cpu thread and matched core have the same node-id */ diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index cd27b4c3af..dcd6a1cf19 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -84,14 +84,34 @@ out: static void s390_init_cpus(MachineState *machine) { MachineClass *mc = MACHINE_GET_CLASS(machine); - int i; + CPUArchId *slot; + int i, n = 0; /* initialize possible_cpus */ mc->possible_cpu_arch_ids(machine); s390_topology_setup(machine); - for (i = 0; i < machine->smp.cpus; i++) { + + /* For NUMA configuration create defined nodes */ + if (machine->numa_state->num_nodes) { + for (i = 0; i < machine->smp.max_cpus; i++) { + slot = &machine->possible_cpus->cpus[i]; + if (slot->arch_id != -1 && n < machine->smp.cpus) { + s390x_new_cpu(machine->cpu_type, i, &error_fatal); + n++; + } + } + } + + /* create all remaining CPUs */ + for (i = 0; n < machine->smp.cpus && i < machine->smp.max_cpus; i++) { + slot = &machine->possible_cpus->cpus[i]; + /* For NUMA configuration skip defined nodes */ + if (machine->numa_state->num_nodes && slot->arch_id != -1) { + continue; + } s390x_new_cpu(machine->cpu_type, i, &error_fatal); + n++; } } @@ -274,6 +294,11 @@ static void ccw_init(MachineState *machine) /* register hypercalls */ virtio_ccw_register_hcalls(); + /* CPU0 must exist on S390x */ + if (!s390_cpu_addr2state(0)) { + error_printf("Core_id 0 must be defined in the CPU configuration\n"); + exit(1); + } s390_enable_css_support(s390_cpu_addr2state(0)); ret = css_create_css_image(VIRTUAL_CSSID, true); @@ -306,6 +331,7 @@ static void s390_cpu_plug(HotplugHandler *hotplug_dev, g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu); ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev); + ms->possible_cpus->cpus[cpu->env.core_id].arch_id = cpu->env.core_id; s390_topology_new_cpu(cpu->env.core_id); @@ -579,7 +605,9 @@ static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms, static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms) { int i; + int drawer_id, book_id, socket_id; unsigned int max_cpus = ms->smp.max_cpus; + CPUArchId *slot; if (ms->possible_cpus) { g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus); @@ -590,11 +618,25 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms) sizeof(CPUArchId) * max_cpus); ms->possible_cpus->len = max_cpus; for (i = 0; i < ms->possible_cpus->len; i++) { - ms->possible_cpus->cpus[i].type = ms->cpu_type; - ms->possible_cpus->cpus[i].vcpus_count = 1; - ms->possible_cpus->cpus[i].arch_id = i; - ms->possible_cpus->cpus[i].props.has_core_id = true; - ms->possible_cpus->cpus[i].props.core_id = i; + slot = &ms->possible_cpus->cpus[i]; + + slot->type = ms->cpu_type; + slot->vcpus_count = 1; + slot->arch_id = i; + slot->props.has_core_id = true; + slot->props.core_id = i; + + socket_id = i / ms->smp.cores; + slot->props.socket_id = socket_id; + slot->props.has_socket_id = true; + + book_id = socket_id / ms->smp.sockets; + slot->props.book_id = book_id; + slot->props.has_book_id = true; + + drawer_id = book_id / ms->smp.books; + slot->props.drawer_id = drawer_id; + slot->props.has_drawer_id = true; } return ms->possible_cpus; @@ -636,6 +678,17 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz) return newsz; } +/* + * S390 defines CPU topology level 2 as the level for which a change in topology + * is worth being taking care of. + * Let use level 2, socket, as the numa node. + */ +static int64_t s390_get_default_cpu_node_id(const MachineState *ms, int idx) +{ + ms->possible_cpus->cpus[idx].arch_id = -1; + return idx / ms->smp.cores; +} + static void ccw_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -668,6 +721,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "s390.ram"; mc->smp_props.books_supported = true; mc->smp_props.drawers_supported = true; + mc->get_default_cpu_node_id = s390_get_default_cpu_node_id; } static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp) -- 2.27.0
WARNING: multiple messages have this Message-ID (diff)
From: Pierre Morel <pmorel@linux.ibm.com> To: qemu-s390x@nongnu.org Cc: thuth@redhat.com, ehabkost@redhat.com, kvm@vger.kernel.org, david@redhat.com, eblake@redhat.com, cohuck@redhat.com, richard.henderson@linaro.org, qemu-devel@nongnu.org, armbru@redhat.com, pasic@linux.ibm.com, borntraeger@de.ibm.com, mst@redhat.com, pbonzini@redhat.com, philmd@redhat.com Subject: [PATCH v5 11/12] s390x: topology: implementing numa for the s390x topology Date: Thu, 9 Dec 2021 14:46:42 +0100 [thread overview] Message-ID: <20211209134643.143866-12-pmorel@linux.ibm.com> (raw) In-Reply-To: <20211209134643.143866-1-pmorel@linux.ibm.com> S390x CPU Topology allows a non uniform repartition of the CPU inside the topology containers, sockets, books and drawers. We use numa to place the CPU inside the right topology container and report the non uniform topology to the guest. Note that s390x needs CPU0 to belong to the topology and consequently all topology must include CPU0. We accept a partial QEMU numa definition, in that case undefined CPUs are added to free slots in the topology starting with slot 0 and going up. Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> --- hw/core/machine.c | 18 ++++++++++ hw/s390x/s390-virtio-ccw.c | 68 ++++++++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 0059070309..d65a91c607 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -684,6 +684,16 @@ void machine_set_cpu_numa_node(MachineState *machine, return; } + if (props->has_book_id && !slot->props.has_book_id) { + error_setg(errp, "book-id is not supported"); + return; + } + + if (props->has_drawer_id && !slot->props.has_drawer_id) { + error_setg(errp, "drawer-id is not supported"); + return; + } + /* skip slots with explicit mismatch */ if (props->has_thread_id && props->thread_id != slot->props.thread_id) { continue; @@ -701,6 +711,14 @@ void machine_set_cpu_numa_node(MachineState *machine, continue; } + if (props->has_book_id && props->book_id != slot->props.book_id) { + continue; + } + + if (props->has_drawer_id && props->drawer_id != slot->props.drawer_id) { + continue; + } + /* reject assignment if slot is already assigned, for compatibility * of legacy cpu_index mapping with SPAPR core based mapping do not * error out if cpu thread and matched core have the same node-id */ diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index cd27b4c3af..dcd6a1cf19 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -84,14 +84,34 @@ out: static void s390_init_cpus(MachineState *machine) { MachineClass *mc = MACHINE_GET_CLASS(machine); - int i; + CPUArchId *slot; + int i, n = 0; /* initialize possible_cpus */ mc->possible_cpu_arch_ids(machine); s390_topology_setup(machine); - for (i = 0; i < machine->smp.cpus; i++) { + + /* For NUMA configuration create defined nodes */ + if (machine->numa_state->num_nodes) { + for (i = 0; i < machine->smp.max_cpus; i++) { + slot = &machine->possible_cpus->cpus[i]; + if (slot->arch_id != -1 && n < machine->smp.cpus) { + s390x_new_cpu(machine->cpu_type, i, &error_fatal); + n++; + } + } + } + + /* create all remaining CPUs */ + for (i = 0; n < machine->smp.cpus && i < machine->smp.max_cpus; i++) { + slot = &machine->possible_cpus->cpus[i]; + /* For NUMA configuration skip defined nodes */ + if (machine->numa_state->num_nodes && slot->arch_id != -1) { + continue; + } s390x_new_cpu(machine->cpu_type, i, &error_fatal); + n++; } } @@ -274,6 +294,11 @@ static void ccw_init(MachineState *machine) /* register hypercalls */ virtio_ccw_register_hcalls(); + /* CPU0 must exist on S390x */ + if (!s390_cpu_addr2state(0)) { + error_printf("Core_id 0 must be defined in the CPU configuration\n"); + exit(1); + } s390_enable_css_support(s390_cpu_addr2state(0)); ret = css_create_css_image(VIRTUAL_CSSID, true); @@ -306,6 +331,7 @@ static void s390_cpu_plug(HotplugHandler *hotplug_dev, g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu); ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev); + ms->possible_cpus->cpus[cpu->env.core_id].arch_id = cpu->env.core_id; s390_topology_new_cpu(cpu->env.core_id); @@ -579,7 +605,9 @@ static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms, static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms) { int i; + int drawer_id, book_id, socket_id; unsigned int max_cpus = ms->smp.max_cpus; + CPUArchId *slot; if (ms->possible_cpus) { g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus); @@ -590,11 +618,25 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms) sizeof(CPUArchId) * max_cpus); ms->possible_cpus->len = max_cpus; for (i = 0; i < ms->possible_cpus->len; i++) { - ms->possible_cpus->cpus[i].type = ms->cpu_type; - ms->possible_cpus->cpus[i].vcpus_count = 1; - ms->possible_cpus->cpus[i].arch_id = i; - ms->possible_cpus->cpus[i].props.has_core_id = true; - ms->possible_cpus->cpus[i].props.core_id = i; + slot = &ms->possible_cpus->cpus[i]; + + slot->type = ms->cpu_type; + slot->vcpus_count = 1; + slot->arch_id = i; + slot->props.has_core_id = true; + slot->props.core_id = i; + + socket_id = i / ms->smp.cores; + slot->props.socket_id = socket_id; + slot->props.has_socket_id = true; + + book_id = socket_id / ms->smp.sockets; + slot->props.book_id = book_id; + slot->props.has_book_id = true; + + drawer_id = book_id / ms->smp.books; + slot->props.drawer_id = drawer_id; + slot->props.has_drawer_id = true; } return ms->possible_cpus; @@ -636,6 +678,17 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz) return newsz; } +/* + * S390 defines CPU topology level 2 as the level for which a change in topology + * is worth being taking care of. + * Let use level 2, socket, as the numa node. + */ +static int64_t s390_get_default_cpu_node_id(const MachineState *ms, int idx) +{ + ms->possible_cpus->cpus[idx].arch_id = -1; + return idx / ms->smp.cores; +} + static void ccw_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -668,6 +721,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "s390.ram"; mc->smp_props.books_supported = true; mc->smp_props.drawers_supported = true; + mc->get_default_cpu_node_id = s390_get_default_cpu_node_id; } static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp) -- 2.27.0
next prev parent reply other threads:[~2021-12-09 13:46 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-12-09 13:46 [PATCH v5 00/12] s390x: CPU Topology Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 01/12] s390x: cpu topology: update linux headers Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 02/12] s390x: SCLP: reporting the maximum nested topology entries Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 03/12] s390x: topology: CPU topology objects and structures Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 04/12] s390x: topology: implementating Store Topology System Information Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 05/12] s390x: CPU topology: CPU topology migration Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 06/12] s390x: kvm: topology: interception of PTF instruction Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 07/12] s390: topology: Adding books to CPU topology Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 08/12] s390: topology: Adding books to STSI Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 09/12] s390: topology: Adding drawers to CPU topology Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` [PATCH v5 10/12] s390: topology: Adding drawers to STSI Pierre Morel 2021-12-09 13:46 ` Pierre Morel 2021-12-09 13:46 ` Pierre Morel [this message] 2021-12-09 13:46 ` [PATCH v5 11/12] s390x: topology: implementing numa for the s390x topology Pierre Morel 2021-12-09 13:46 ` [PATCH v5 12/12] s390: Topology: documentation Pierre Morel 2021-12-09 13:46 ` Pierre Morel
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211209134643.143866-12-pmorel@linux.ibm.com \ --to=pmorel@linux.ibm.com \ --cc=armbru@redhat.com \ --cc=borntraeger@de.ibm.com \ --cc=cohuck@redhat.com \ --cc=david@redhat.com \ --cc=eblake@redhat.com \ --cc=ehabkost@redhat.com \ --cc=kvm@vger.kernel.org \ --cc=marcel.apfelbaum@gmail.com \ --cc=mst@redhat.com \ --cc=pasic@linux.ibm.com \ --cc=pbonzini@redhat.com \ --cc=philmd@redhat.com \ --cc=qemu-devel@nongnu.org \ --cc=qemu-s390x@nongnu.org \ --cc=richard.henderson@linaro.org \ --cc=thuth@redhat.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.