mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 16:23:55 -06:00
CPU topology: extend with s390 specifics
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. Add the new levels to the relevant QAPI structs. Add all the supported topology levels, dedication and entitlement as properties to S390 CPUs. Create 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> Message-ID: <20231016183925.2384704-3-nsg@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
3da4aef81c
commit
5de1aff255
15 changed files with 141 additions and 13 deletions
|
@ -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: "
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue