Message ID | 20231005160155.1945588-3-nsg@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: CPU Topology | expand |
Nina Schoetterl-Glausch <nsg@linux.ibm.com> writes: > From: Pierre Morel <pmorel@linux.ibm.com> > > S390 adds two new SMP levels, drawers and books to the CPU > topology. > S390 CPUs have specific topology features like dedication and > entitlement. These indicate to the guest information on host > vCPU scheduling and help the guest make better scheduling decisions. > > Let us provide the SMP properties with books and drawers levels > and S390 CPU with dedication and entitlement, This is vague. Peeking at the patch, I can see it adds properties "socket-id", "book-id", "drawer-id", "dedicated", and "entitlement" to "s390x-cpu" objects. Suggest to spell that out here. > Add machine-common.json so we can later include it in > machine-target.json also. > > Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> > Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> > Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> > Reviewed-by: Thomas Huth <thuth@redhat.com> > Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> > --- > MAINTAINERS | 1 + > qapi/machine-common.json | 21 +++++++++++++ > qapi/machine.json | 17 +++++++++- > qapi/qapi-schema.json | 1 + > include/hw/boards.h | 10 +++++- > include/hw/qdev-properties-system.h | 4 +++ > target/s390x/cpu.h | 6 ++++ > hw/core/machine-smp.c | 48 ++++++++++++++++++++++++----- > hw/core/machine.c | 4 +++ > hw/core/qdev-properties-system.c | 13 ++++++++ > hw/s390x/s390-virtio-ccw.c | 4 +++ > softmmu/vl.c | 6 ++++ > target/s390x/cpu.c | 7 +++++ > qapi/meson.build | 1 + > qemu-options.hx | 7 +++-- > 15 files changed, 139 insertions(+), 11 deletions(-) > create mode 100644 qapi/machine-common.json > > diff --git a/MAINTAINERS b/MAINTAINERS > index 81625f036b..3f6888aa86 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1775,6 +1775,7 @@ F: hw/core/null-machine.c > F: hw/core/numa.c > F: hw/cpu/cluster.c > F: qapi/machine.json > +F: qapi/machine-common.json > F: qapi/machine-target.json > F: include/hw/boards.h > F: include/hw/core/cpu.h > diff --git a/qapi/machine-common.json b/qapi/machine-common.json > new file mode 100644 > index 0000000000..fa6bd71d12 > --- /dev/null > +++ b/qapi/machine-common.json > @@ -0,0 +1,21 @@ > +# -*- Mode: Python -*- > +# vim: filetype=python > +# > +# This work is licensed under the terms of the GNU GPL, version 2 or later. > +# See the COPYING file in the top-level directory. > + > +## > +# = Machines S390 data types > +## > + > +## > +# @CpuS390Entitlement: > +# > +# An enumeration of CPU entitlements that can be assumed by a virtual > +# S390 CPU > +# > +# Since: 8.2 > +## > +{ 'enum': 'CpuS390Entitlement', > + 'prefix': 'S390_CPU_ENTITLEMENT', > + 'data': [ 'auto', 'low', 'medium', 'high' ] } > diff --git a/qapi/machine.json b/qapi/machine.json > index 40b835e28e..7aacd26af0 100644 > --- a/qapi/machine.json > +++ b/qapi/machine.json > @@ -9,6 +9,7 @@ > ## > > { 'include': 'common.json' } > +{ 'include': 'machine-common.json' } > > ## > # @SysEmuTarget: > @@ -904,7 +905,13 @@ > # > # @node-id: NUMA node ID the CPU belongs to > # > -# @socket-id: socket number within node/board the CPU belongs to > +# @drawer-id: drawer number within node/board the CPU belongs to > +# (since 8.2) > +# > +# @book-id: book number within drawer/node/board the CPU belongs to > +# (since 8.2) > +# > +# @socket-id: socket number within book/node/board the CPU belongs to > # > # @die-id: die number within socket the CPU belongs to (since 4.1) > # # @cluster-id: cluster number within die the CPU belongs to (since # 7.1) # # @core-id: core number within cluster the CPU belongs to # # @thread-id: thread number within core the CPU belongs to So... * A thread can only be within a core * A core can only be within a cluster * A cluster can only be within a die * A die can only be within a socket * A socket can be within a book, node, or board * A book can be within a drawer, node, or board * A drawer can be within a node, or board * A node is a NUMA node * A board is what exactly? can we have more than one? is node always within a/the board? Asked differently: what are the possible hierarchies of things? > @@ -923,6 +930,8 @@ > { 'struct': 'CpuInstanceProperties', > # Keep these in sync with the properties device_add accepts > 'data': { '*node-id': 'int', > + '*drawer-id': 'int', > + '*book-id': 'int', > '*socket-id': 'int', > '*die-id': 'int', > '*cluster-id': 'int', > @@ -1481,6 +1490,10 @@ > # > # @cpus: number of virtual CPUs in the virtual machine > # > +# @drawers: number of drawers in the CPU topology (since 8.2) > +# > +# @books: number of books in the CPU topology (since 8.2) > +# > # @sockets: number of sockets in the CPU topology Total numer of sockets? Or number of sockets per whatever thing contains sockets? Same question for @books, @drawers, and @cpus. The documentation is less than clear before your patch; your patch merely makes me look at it. We may decide that addressing the lack of clarity is not your patch's job, and leave it for later. > # > # @dies: number of dies per socket in the CPU topology > @@ -1499,6 +1512,8 @@ > ## > { 'struct': 'SMPConfiguration', 'data': { > '*cpus': 'int', > + '*drawers': 'int', > + '*books': 'int', > '*sockets': 'int', > '*dies': 'int', > '*clusters': 'int', > diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json > index 6594afba31..c01ec335e6 100644 > --- a/qapi/qapi-schema.json > +++ b/qapi/qapi-schema.json > @@ -66,6 +66,7 @@ > { 'include': 'introspect.json' } > { 'include': 'qom.json' } > { 'include': 'qdev.json' } > +{ 'include': 'machine-common.json' } > { 'include': 'machine.json' } > { 'include': 'machine-target.json' } > { 'include': 'replay.json' } [...] > diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c > index df167493c3..74405beb51 100644 > --- a/target/s390x/cpu.c > +++ b/target/s390x/cpu.c > @@ -31,6 +31,7 @@ > #include "qapi/qapi-types-machine.h" > #include "sysemu/hw_accel.h" > #include "hw/qdev-properties.h" > +#include "hw/qdev-properties-system.h" > #include "fpu/softfloat-helpers.h" > #include "disas/capstone.h" > #include "sysemu/tcg.h" > @@ -292,6 +293,12 @@ static gchar *s390_gdb_arch_name(CPUState *cs) > static Property s390x_cpu_properties[] = { > #if !defined(CONFIG_USER_ONLY) > DEFINE_PROP_UINT32("core-id", S390CPU, env.core_id, 0), > + DEFINE_PROP_INT32("socket-id", S390CPU, env.socket_id, -1), > + DEFINE_PROP_INT32("book-id", S390CPU, env.book_id, -1), > + DEFINE_PROP_INT32("drawer-id", S390CPU, env.drawer_id, -1), > + DEFINE_PROP_BOOL("dedicated", S390CPU, env.dedicated, false), > + DEFINE_PROP_CPUS390ENTITLEMENT("entitlement", S390CPU, env.entitlement, > + S390_CPU_ENTITLEMENT_AUTO), > #endif > DEFINE_PROP_END_OF_LIST() > }; [...] I suspect the patch could be split into a part that updates CpuInstanceProperties and SMPConfiguration, and a part that adds the properties. Since the series is at v25, I'm *not* asking you explore that.
On Thu, 2023-10-12 at 13:02 +0200, Markus Armbruster wrote: > Nina Schoetterl-Glausch <nsg@linux.ibm.com> writes: > > > From: Pierre Morel <pmorel@linux.ibm.com> > > > > S390 adds two new SMP levels, drawers and books to the CPU > > topology. > > S390 CPUs have specific topology features like dedication and > > entitlement. These indicate to the guest information on host > > vCPU scheduling and help the guest make better scheduling decisions. > > > > Let us provide the SMP properties with books and drawers levels > > and S390 CPU with dedication and entitlement, > > This is vague. Peeking at the patch, I can see it adds properties > "socket-id", "book-id", "drawer-id", "dedicated", and "entitlement" to > "s390x-cpu" objects. Suggest to spell that out here. > > > Add machine-common.json so we can later include it in > > machine-target.json also. > > > > Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> > > Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> > > Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> > > Reviewed-by: Thomas Huth <thuth@redhat.com> > > Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> > > --- > > MAINTAINERS | 1 + > > qapi/machine-common.json | 21 +++++++++++++ > > qapi/machine.json | 17 +++++++++- > > qapi/qapi-schema.json | 1 + > > include/hw/boards.h | 10 +++++- > > include/hw/qdev-properties-system.h | 4 +++ > > target/s390x/cpu.h | 6 ++++ > > hw/core/machine-smp.c | 48 ++++++++++++++++++++++++----- > > hw/core/machine.c | 4 +++ > > hw/core/qdev-properties-system.c | 13 ++++++++ > > hw/s390x/s390-virtio-ccw.c | 4 +++ > > softmmu/vl.c | 6 ++++ > > target/s390x/cpu.c | 7 +++++ > > qapi/meson.build | 1 + > > qemu-options.hx | 7 +++-- > > 15 files changed, 139 insertions(+), 11 deletions(-) > > create mode 100644 qapi/machine-common.json > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 81625f036b..3f6888aa86 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -1775,6 +1775,7 @@ F: hw/core/null-machine.c > > F: hw/core/numa.c > > F: hw/cpu/cluster.c > > F: qapi/machine.json > > +F: qapi/machine-common.json > > F: qapi/machine-target.json > > F: include/hw/boards.h > > F: include/hw/core/cpu.h > > diff --git a/qapi/machine-common.json b/qapi/machine-common.json > > new file mode 100644 > > index 0000000000..fa6bd71d12 [...] > > ## > > # @SysEmuTarget: > > @@ -904,7 +905,13 @@ > > # > > # @node-id: NUMA node ID the CPU belongs to > > # > > -# @socket-id: socket number within node/board the CPU belongs to > > +# @drawer-id: drawer number within node/board the CPU belongs to > > +# (since 8.2) > > +# > > +# @book-id: book number within drawer/node/board the CPU belongs to > > +# (since 8.2) > > +# > > +# @socket-id: socket number within book/node/board the CPU belongs to > > # > > # @die-id: die number within socket the CPU belongs to (since 4.1) > > # > # @cluster-id: cluster number within die the CPU belongs to (since > # 7.1) > # > # @core-id: core number within cluster the CPU belongs to > # > # @thread-id: thread number within core the CPU belongs to > > So... > > * A thread can only be within a core > > * A core can only be within a cluster > > * A cluster can only be within a die > > * A die can only be within a socket > > * A socket can be within a book, node, or board > > * A book can be within a drawer, node, or board > > * A drawer can be within a node, or board > > * A node is a NUMA node > > * A board is what exactly? can we have more than one? is node always > within a/the board? Yeah, the description is confusing. > > Asked differently: what are the possible hierarchies of things? The way I understand things is: * Different architectures have different hierarchies, say 1. (thread, core, cluster, die, socket) 2. (thread, core, socket, book, drawer) We define a qemu artificial ordered super set (thread, core, cluster, die, socket, book, drawer) where architectures can choose a subset of, specifying that they support a certain level or not. Now if for example x86 wanted to support a book level between thread and core, we'd need to change a bunch of code and make things more complicated. The NUMA node-id maps a hierarchy tuple to a node, I don't think it's part of hierarchy itself. Now the question is how to document this. On s390x there is no cluster, so what does @core-id: core number within cluster the CPU belongs to mean? We could say, that within the qemu super set there is a virtual cluster of which there is one per die (and one die per socket). Or we rewrite the documentation to say @x-id: x number within the upper hierarchy container to account for the fact that the upper container is different on different architectures. > > > @@ -923,6 +930,8 @@ > > { 'struct': 'CpuInstanceProperties', > > # Keep these in sync with the properties device_add accepts > > 'data': { '*node-id': 'int', > > + '*drawer-id': 'int', > > + '*book-id': 'int', > > '*socket-id': 'int', > > '*die-id': 'int', > > '*cluster-id': 'int', > > @@ -1481,6 +1490,10 @@ > > # > > # @cpus: number of virtual CPUs in the virtual machine > > # > > +# @drawers: number of drawers in the CPU topology (since 8.2) > > +# > > +# @books: number of books in the CPU topology (since 8.2) > > +# > > # @sockets: number of sockets in the CPU topology > > Total numer of sockets? Or number of sockets per whatever thing > contains sockets? The latter. I'll change this > > Same question for @books, @drawers, and @cpus. Same for the first two, total for @cpus. > > The documentation is less than clear before your patch; your patch > merely makes me look at it. We may decide that addressing the lack of > clarity is not your patch's job, and leave it for later. Yeah, same problem here around different architectures using different sub sets. > > > # > > # @dies: number of dies per socket in the CPU topology > > @@ -1499,6 +1512,8 @@ > > ## > > { 'struct': 'SMPConfiguration', 'data': { > > '*cpus': 'int', > > + '*drawers': 'int', > > + '*books': 'int', > > '*sockets': 'int', > > '*dies': 'int', > > '*clusters': 'int', [...]
Nina Schoetterl-Glausch <nsg@linux.ibm.com> writes: > On Thu, 2023-10-12 at 13:02 +0200, Markus Armbruster wrote: >> Nina Schoetterl-Glausch <nsg@linux.ibm.com> writes: >> >> > From: Pierre Morel <pmorel@linux.ibm.com> >> > >> > S390 adds two new SMP levels, drawers and books to the CPU >> > topology. >> > S390 CPUs have specific topology features like dedication and >> > entitlement. These indicate to the guest information on host >> > vCPU scheduling and help the guest make better scheduling decisions. >> > >> > Let us provide the SMP properties with books and drawers levels >> > and S390 CPU with dedication and entitlement, >> >> This is vague. Peeking at the patch, I can see it adds properties >> "socket-id", "book-id", "drawer-id", "dedicated", and "entitlement" to >> "s390x-cpu" objects. Suggest to spell that out here. >> >> > Add machine-common.json so we can later include it in >> > machine-target.json also. >> > >> > Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> >> > Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> >> > Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> >> > Reviewed-by: Thomas Huth <thuth@redhat.com> >> > Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> >> > --- >> > MAINTAINERS | 1 + >> > qapi/machine-common.json | 21 +++++++++++++ >> > qapi/machine.json | 17 +++++++++- >> > qapi/qapi-schema.json | 1 + >> > include/hw/boards.h | 10 +++++- >> > include/hw/qdev-properties-system.h | 4 +++ >> > target/s390x/cpu.h | 6 ++++ >> > hw/core/machine-smp.c | 48 ++++++++++++++++++++++++----- >> > hw/core/machine.c | 4 +++ >> > hw/core/qdev-properties-system.c | 13 ++++++++ >> > hw/s390x/s390-virtio-ccw.c | 4 +++ >> > softmmu/vl.c | 6 ++++ >> > target/s390x/cpu.c | 7 +++++ >> > qapi/meson.build | 1 + >> > qemu-options.hx | 7 +++-- >> > 15 files changed, 139 insertions(+), 11 deletions(-) >> > create mode 100644 qapi/machine-common.json >> > >> > diff --git a/MAINTAINERS b/MAINTAINERS >> > index 81625f036b..3f6888aa86 100644 >> > --- a/MAINTAINERS >> > +++ b/MAINTAINERS >> > @@ -1775,6 +1775,7 @@ F: hw/core/null-machine.c >> > F: hw/core/numa.c >> > F: hw/cpu/cluster.c >> > F: qapi/machine.json >> > +F: qapi/machine-common.json >> > F: qapi/machine-target.json >> > F: include/hw/boards.h >> > F: include/hw/core/cpu.h >> > diff --git a/qapi/machine-common.json b/qapi/machine-common.json >> > new file mode 100644 >> > index 0000000000..fa6bd71d12 > > [...] > >> > ## >> > # @SysEmuTarget: >> > @@ -904,7 +905,13 @@ >> > # >> > # @node-id: NUMA node ID the CPU belongs to >> > # >> > -# @socket-id: socket number within node/board the CPU belongs to >> > +# @drawer-id: drawer number within node/board the CPU belongs to >> > +# (since 8.2) >> > +# >> > +# @book-id: book number within drawer/node/board the CPU belongs to >> > +# (since 8.2) >> > +# >> > +# @socket-id: socket number within book/node/board the CPU belongs to >> > # >> > # @die-id: die number within socket the CPU belongs to (since 4.1) >> > # >> # @cluster-id: cluster number within die the CPU belongs to (since >> # 7.1) >> # >> # @core-id: core number within cluster the CPU belongs to >> # >> # @thread-id: thread number within core the CPU belongs to >> >> So... >> >> * A thread can only be within a core >> >> * A core can only be within a cluster >> >> * A cluster can only be within a die >> >> * A die can only be within a socket >> >> * A socket can be within a book, node, or board >> >> * A book can be within a drawer, node, or board >> >> * A drawer can be within a node, or board >> >> * A node is a NUMA node >> >> * A board is what exactly? can we have more than one? is node always >> within a/the board? > > Yeah, the description is confusing. >> >> Asked differently: what are the possible hierarchies of things? > > The way I understand things is: > * Different architectures have different hierarchies, say > 1. (thread, core, cluster, die, socket) > 2. (thread, core, socket, book, drawer) > > We define a qemu artificial ordered super set > (thread, core, cluster, die, socket, book, drawer) > where architectures can choose a subset of, specifying that they > support a certain level or not. > > Now if for example x86 wanted to support a book level between > thread and core, we'd need to change a bunch of code and make > things more complicated. > > The NUMA node-id maps a hierarchy tuple to a node, I don't think > it's part of hierarchy itself. > > Now the question is how to document this. Right. > On s390x there is no cluster, so what does > > @core-id: core number within cluster the CPU belongs to > > mean? > > We could say, that within the qemu super set there is a virtual > cluster of which there is one per die (and one die per socket). > > Or we rewrite the documentation to say > > @x-id: x number within the upper hierarchy container > > to account for the fact that the upper container is different > on different architectures. Perhaps a structure like this could work. 1. Define the most general hierarchy. 2. Explain the actual hierarchy is a subset. 3. Explain the members as "number within container", as you proposed. Only works if a superset of all the actual hierarchies exists, and is sufficiently easy explain. >> > @@ -923,6 +930,8 @@ >> > { 'struct': 'CpuInstanceProperties', >> > # Keep these in sync with the properties device_add accepts >> > 'data': { '*node-id': 'int', >> > + '*drawer-id': 'int', >> > + '*book-id': 'int', >> > '*socket-id': 'int', >> > '*die-id': 'int', >> > '*cluster-id': 'int', >> > @@ -1481,6 +1490,10 @@ >> > # >> > # @cpus: number of virtual CPUs in the virtual machine >> > # >> > +# @drawers: number of drawers in the CPU topology (since 8.2) >> > +# >> > +# @books: number of books in the CPU topology (since 8.2) >> > +# >> > # @sockets: number of sockets in the CPU topology >> >> Total numer of sockets? Or number of sockets per whatever thing >> contains sockets? > > The latter. I'll change this >> >> Same question for @books, @drawers, and @cpus. > > Same for the first two, total for @cpus. >> >> The documentation is less than clear before your patch; your patch >> merely makes me look at it. We may decide that addressing the lack of >> clarity is not your patch's job, and leave it for later. > > Yeah, same problem here around different architectures using different sub sets. >> >> > # >> > # @dies: number of dies per socket in the CPU topology >> > @@ -1499,6 +1512,8 @@ >> > ## >> > { 'struct': 'SMPConfiguration', 'data': { >> > '*cpus': 'int', >> > + '*drawers': 'int', >> > + '*books': 'int', >> > '*sockets': 'int', >> > '*dies': 'int', >> > '*clusters': 'int', > > [...] Thanks!
diff --git a/MAINTAINERS b/MAINTAINERS index 81625f036b..3f6888aa86 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1775,6 +1775,7 @@ F: hw/core/null-machine.c F: hw/core/numa.c F: hw/cpu/cluster.c F: qapi/machine.json +F: qapi/machine-common.json F: qapi/machine-target.json F: include/hw/boards.h F: include/hw/core/cpu.h diff --git a/qapi/machine-common.json b/qapi/machine-common.json new file mode 100644 index 0000000000..fa6bd71d12 --- /dev/null +++ b/qapi/machine-common.json @@ -0,0 +1,21 @@ +# -*- Mode: Python -*- +# vim: filetype=python +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# = Machines S390 data types +## + +## +# @CpuS390Entitlement: +# +# An enumeration of CPU entitlements that can be assumed by a virtual +# S390 CPU +# +# Since: 8.2 +## +{ 'enum': 'CpuS390Entitlement', + 'prefix': 'S390_CPU_ENTITLEMENT', + 'data': [ 'auto', 'low', 'medium', 'high' ] } diff --git a/qapi/machine.json b/qapi/machine.json index 40b835e28e..7aacd26af0 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -9,6 +9,7 @@ ## { 'include': 'common.json' } +{ 'include': 'machine-common.json' } ## # @SysEmuTarget: @@ -904,7 +905,13 @@ # # @node-id: NUMA node ID the CPU belongs to # -# @socket-id: socket number within node/board the CPU belongs to +# @drawer-id: drawer number within node/board the CPU belongs to +# (since 8.2) +# +# @book-id: book number within drawer/node/board the CPU belongs to +# (since 8.2) +# +# @socket-id: socket number within book/node/board the CPU belongs to # # @die-id: die number within socket the CPU belongs to (since 4.1) # @@ -923,6 +930,8 @@ { 'struct': 'CpuInstanceProperties', # Keep these in sync with the properties device_add accepts 'data': { '*node-id': 'int', + '*drawer-id': 'int', + '*book-id': 'int', '*socket-id': 'int', '*die-id': 'int', '*cluster-id': 'int', @@ -1481,6 +1490,10 @@ # # @cpus: number of virtual CPUs in the virtual machine # +# @drawers: number of drawers in the CPU topology (since 8.2) +# +# @books: number of books in the CPU topology (since 8.2) +# # @sockets: number of sockets in the CPU topology # # @dies: number of dies per socket in the CPU topology @@ -1499,6 +1512,8 @@ ## { 'struct': 'SMPConfiguration', 'data': { '*cpus': 'int', + '*drawers': 'int', + '*books': 'int', '*sockets': 'int', '*dies': 'int', '*clusters': 'int', diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 6594afba31..c01ec335e6 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -66,6 +66,7 @@ { 'include': 'introspect.json' } { 'include': 'qom.json' } { 'include': 'qdev.json' } +{ 'include': 'machine-common.json' } { 'include': 'machine.json' } { 'include': 'machine-target.json' } { 'include': 'replay.json' } diff --git a/include/hw/boards.h b/include/hw/boards.h index 55a64a13fd..6237ea39d9 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -135,12 +135,16 @@ typedef struct { * @clusters_supported - whether clusters are supported by the machine * @has_clusters - whether clusters are explicitly specified in the user * provided SMP configuration + * @books_supported - whether books are supported by the machine + * @drawers_supported - whether drawers are supported by the machine */ typedef struct { bool prefer_sockets; bool dies_supported; bool clusters_supported; bool has_clusters; + bool books_supported; + bool drawers_supported; } SMPCompatProps; /** @@ -311,7 +315,9 @@ typedef struct DeviceMemoryState { /** * CpuTopology: * @cpus: the number of present logical processors on the machine - * @sockets: the number of sockets on the machine + * @drawers: the number of drawers on the machine + * @books: the number of books in one drawer + * @sockets: the number of sockets in one book * @dies: the number of dies in one socket * @clusters: the number of clusters in one die * @cores: the number of cores in one cluster @@ -320,6 +326,8 @@ typedef struct DeviceMemoryState { */ typedef struct CpuTopology { unsigned int cpus; + unsigned int drawers; + unsigned int books; unsigned int sockets; unsigned int dies; unsigned int clusters; diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h index 0ac327ae60..e4f8a13afc 100644 --- a/include/hw/qdev-properties-system.h +++ b/include/hw/qdev-properties-system.h @@ -22,6 +22,7 @@ extern const PropertyInfo qdev_prop_audiodev; extern const PropertyInfo qdev_prop_off_auto_pcibar; extern const PropertyInfo qdev_prop_pcie_link_speed; extern const PropertyInfo qdev_prop_pcie_link_width; +extern const PropertyInfo qdev_prop_cpus390entitlement; #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) @@ -73,5 +74,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width; #define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) \ DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID) +#define DEFINE_PROP_CPUS390ENTITLEMENT(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \ + CpuS390Entitlement) #endif diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index 304029e57c..dfcc1aa1fc 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -30,6 +30,7 @@ #include "exec/cpu-defs.h" #include "qemu/cpu-float.h" #include "tcg/tcg_s390x.h" +#include "qapi/qapi-types-machine-common.h" #define ELF_MACHINE_UNAME "S390X" @@ -132,6 +133,11 @@ struct CPUArchState { #if !defined(CONFIG_USER_ONLY) uint32_t core_id; /* PoP "CPU address", same as cpu_index */ + int32_t socket_id; + int32_t book_id; + int32_t drawer_id; + bool dedicated; + CpuS390Entitlement entitlement; /* Used only for vertical polarization */ uint64_t cpuid; #endif diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index 0f4d9b6f7a..25019c91ee 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -33,6 +33,14 @@ static char *cpu_hierarchy_to_string(MachineState *ms) MachineClass *mc = MACHINE_GET_CLASS(ms); GString *s = g_string_new(NULL); + if (mc->smp_props.drawers_supported) { + g_string_append_printf(s, "drawers (%u) * ", ms->smp.drawers); + } + + if (mc->smp_props.books_supported) { + g_string_append_printf(s, "books (%u) * ", ms->smp.books); + } + g_string_append_printf(s, "sockets (%u)", ms->smp.sockets); if (mc->smp_props.dies_supported) { @@ -75,6 +83,8 @@ void machine_parse_smp_config(MachineState *ms, { MachineClass *mc = MACHINE_GET_CLASS(ms); unsigned cpus = config->has_cpus ? config->cpus : 0; + unsigned drawers = config->has_drawers ? config->drawers : 0; + unsigned books = config->has_books ? config->books : 0; unsigned sockets = config->has_sockets ? config->sockets : 0; unsigned dies = config->has_dies ? config->dies : 0; unsigned clusters = config->has_clusters ? config->clusters : 0; @@ -87,6 +97,8 @@ void machine_parse_smp_config(MachineState *ms, * explicit configuration like "cpus=0" is not allowed. */ if ((config->has_cpus && config->cpus == 0) || + (config->has_drawers && config->drawers == 0) || + (config->has_books && config->books == 0) || (config->has_sockets && config->sockets == 0) || (config->has_dies && config->dies == 0) || (config->has_clusters && config->clusters == 0) || @@ -113,6 +125,19 @@ void machine_parse_smp_config(MachineState *ms, dies = dies > 0 ? dies : 1; clusters = clusters > 0 ? clusters : 1; + if (!mc->smp_props.books_supported && books > 1) { + error_setg(errp, "books not supported by this machine's CPU topology"); + return; + } + books = books > 0 ? books : 1; + + if (!mc->smp_props.drawers_supported && drawers > 1) { + error_setg(errp, + "drawers not supported by this machine's CPU topology"); + return; + } + drawers = drawers > 0 ? drawers : 1; + /* compute missing values based on the provided ones */ if (cpus == 0 && maxcpus == 0) { sockets = sockets > 0 ? sockets : 1; @@ -126,33 +151,41 @@ void machine_parse_smp_config(MachineState *ms, if (sockets == 0) { cores = cores > 0 ? cores : 1; threads = threads > 0 ? threads : 1; - sockets = maxcpus / (dies * clusters * cores * threads); + sockets = maxcpus / + (drawers * books * dies * clusters * cores * threads); } else if (cores == 0) { threads = threads > 0 ? threads : 1; - cores = maxcpus / (sockets * dies * clusters * threads); + cores = maxcpus / + (drawers * books * sockets * dies * clusters * threads); } } else { /* prefer cores over sockets since 6.2 */ if (cores == 0) { sockets = sockets > 0 ? sockets : 1; threads = threads > 0 ? threads : 1; - cores = maxcpus / (sockets * dies * clusters * threads); + cores = maxcpus / + (drawers * books * sockets * dies * clusters * threads); } else if (sockets == 0) { threads = threads > 0 ? threads : 1; - sockets = maxcpus / (dies * clusters * cores * threads); + sockets = maxcpus / + (drawers * books * dies * clusters * cores * threads); } } /* try to calculate omitted threads at last */ if (threads == 0) { - threads = maxcpus / (sockets * dies * clusters * cores); + threads = maxcpus / + (drawers * books * sockets * dies * clusters * cores); } } - maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * clusters * cores * threads; + maxcpus = maxcpus > 0 ? maxcpus : drawers * books * sockets * dies * + clusters * cores * threads; cpus = cpus > 0 ? cpus : maxcpus; ms->smp.cpus = cpus; + ms->smp.drawers = drawers; + ms->smp.books = books; ms->smp.sockets = sockets; ms->smp.dies = dies; ms->smp.clusters = clusters; @@ -163,7 +196,8 @@ void machine_parse_smp_config(MachineState *ms, mc->smp_props.has_clusters = config->has_clusters; /* sanity-check of the computed topology */ - if (sockets * dies * clusters * cores * threads != maxcpus) { + if (drawers * books * sockets * dies * clusters * cores * threads != + maxcpus) { g_autofree char *topo_msg = cpu_hierarchy_to_string(ms); error_setg(errp, "Invalid CPU topology: " "product of the hierarchy must match maxcpus: " diff --git a/hw/core/machine.c b/hw/core/machine.c index b135d12b40..e497258b81 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -868,6 +868,8 @@ static void machine_get_smp(Object *obj, Visitor *v, const char *name, MachineState *ms = MACHINE(obj); SMPConfiguration *config = &(SMPConfiguration){ .has_cpus = true, .cpus = ms->smp.cpus, + .has_drawers = true, .drawers = ms->smp.drawers, + .has_books = true, .books = ms->smp.books, .has_sockets = true, .sockets = ms->smp.sockets, .has_dies = true, .dies = ms->smp.dies, .has_clusters = true, .clusters = ms->smp.clusters, @@ -1142,6 +1144,8 @@ static void machine_initfn(Object *obj) /* default to mc->default_cpus */ ms->smp.cpus = mc->default_cpus; ms->smp.max_cpus = mc->default_cpus; + ms->smp.drawers = 1; + ms->smp.books = 1; ms->smp.sockets = 1; ms->smp.dies = 1; ms->smp.clusters = 1; diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 688340610e..7c6dfab128 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -1139,3 +1139,16 @@ const PropertyInfo qdev_prop_uuid = { .set = set_uuid, .set_default_value = set_default_uuid_auto, }; + +/* --- s390 cpu entitlement policy --- */ + +QEMU_BUILD_BUG_ON(sizeof(CpuS390Entitlement) != sizeof(int)); + +const PropertyInfo qdev_prop_cpus390entitlement = { + .name = "CpuS390Entitlement", + .description = "low/medium (default)/high", + .enum_table = &CpuS390Entitlement_lookup, + .get = qdev_propinfo_get_enum, + .set = qdev_propinfo_set_enum, + .set_default_value = qdev_propinfo_set_default_value_enum, +}; diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 2d75f2131f..c1123a9b45 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -744,6 +744,8 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) mc->no_sdcard = 1; mc->max_cpus = S390_MAX_CPUS; mc->has_hotpluggable_cpus = true; + mc->smp_props.books_supported = true; + mc->smp_props.drawers_supported = true; assert(!mc->get_hotplug_handler); mc->get_hotplug_handler = s390_get_hotplug_handler; mc->cpu_index_to_instance_props = s390_cpu_index_to_props; @@ -853,6 +855,8 @@ static void ccw_machine_8_1_class_options(MachineClass *mc) { ccw_machine_8_2_class_options(mc); compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len); + mc->smp_props.drawers_supported = false; + mc->smp_props.books_supported = false; } DEFINE_CCW_MACHINE(8_1, "8.1", false); diff --git a/softmmu/vl.c b/softmmu/vl.c index 98e071e63b..e95bb02333 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -724,6 +724,12 @@ static QemuOptsList qemu_smp_opts = { { .name = "cpus", .type = QEMU_OPT_NUMBER, + }, { + .name = "drawers", + .type = QEMU_OPT_NUMBER, + }, { + .name = "books", + .type = QEMU_OPT_NUMBER, }, { .name = "sockets", .type = QEMU_OPT_NUMBER, diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index df167493c3..74405beb51 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -31,6 +31,7 @@ #include "qapi/qapi-types-machine.h" #include "sysemu/hw_accel.h" #include "hw/qdev-properties.h" +#include "hw/qdev-properties-system.h" #include "fpu/softfloat-helpers.h" #include "disas/capstone.h" #include "sysemu/tcg.h" @@ -292,6 +293,12 @@ static gchar *s390_gdb_arch_name(CPUState *cs) static Property s390x_cpu_properties[] = { #if !defined(CONFIG_USER_ONLY) DEFINE_PROP_UINT32("core-id", S390CPU, env.core_id, 0), + DEFINE_PROP_INT32("socket-id", S390CPU, env.socket_id, -1), + DEFINE_PROP_INT32("book-id", S390CPU, env.book_id, -1), + DEFINE_PROP_INT32("drawer-id", S390CPU, env.drawer_id, -1), + DEFINE_PROP_BOOL("dedicated", S390CPU, env.dedicated, false), + DEFINE_PROP_CPUS390ENTITLEMENT("entitlement", S390CPU, env.entitlement, + S390_CPU_ENTITLEMENT_AUTO), #endif DEFINE_PROP_END_OF_LIST() }; diff --git a/qapi/meson.build b/qapi/meson.build index 60a668b343..f81a37565c 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -36,6 +36,7 @@ qapi_all_modules = [ 'error', 'introspect', 'job', + 'machine-common', 'machine', 'machine-target', 'migration', diff --git a/qemu-options.hx b/qemu-options.hx index 9ce8a5b957..108944cf91 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -272,11 +272,14 @@ SRST ERST DEF("smp", HAS_ARG, QEMU_OPTION_smp, - "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]\n" + "-smp [[cpus=]n][,maxcpus=maxcpus][,drawers=drawers][,books=books][,sockets=sockets]\n" + " [,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]\n" " set the number of initial CPUs to 'n' [default=1]\n" " maxcpus= maximum number of total CPUs, including\n" " offline CPUs for hotplug, etc\n" - " sockets= number of sockets on the machine board\n" + " drawers= number of drawers on the machine board\n" + " books= number of books in one drawer\n" + " sockets= number of sockets in one book\n" " dies= number of dies in one socket\n" " clusters= number of clusters in one die\n" " cores= number of cores in one cluster\n"