aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-12-31 09:33:56 -0800
committerRichard Henderson <richard.henderson@linaro.org>2021-12-31 09:33:56 -0800
commit814a0505302d6af277557f10f88d3639eff7a547 (patch)
treeb40e7bf8b74a28bfe03e5b9cf66cec5244a22f36 /hw
parent69f153667fce723ee546d2f047d66d0cfa67c3cc (diff)
parent2ece6e64846e1929c4ed338c73328d3b126e48d3 (diff)
downloadqemu-814a0505302d6af277557f10f88d3639eff7a547.zip
qemu-814a0505302d6af277557f10f88d3639eff7a547.tar.gz
qemu-814a0505302d6af277557f10f88d3639eff7a547.tar.bz2
Merge tag 'machine-core-20211231' of https://github.com/philmd/qemu into staging
Machine core patches - Clarify qdev_connect_gpio_out() documentation - Rework test-smp-parse tests following QOM style - Introduce CPU cluster topology support (Yanan Wang) - MAINTAINERS updates (Yanan Wang, Li Zhijian, myself) # gpg: Signature made Fri 31 Dec 2021 04:45:35 AM PST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] * tag 'machine-core-20211231' of https://github.com/philmd/qemu: MAINTAINERS: email address change MAINTAINERS: Change philmd's email address MAINTAINERS: Self-recommended as reviewer of "Machine core" tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in machine_base_class_init tests/unit/test-smp-parse: No need to explicitly zero MachineClass members tests/unit/test-smp-parse: Add testcases for CPU clusters hw/core/machine: Introduce CPU cluster topology support qemu-options: Improve readability of SMP related Docs hw/core: Rename smp_parse() -> machine_parse_smp_config() tests/unit/test-smp-parse: Constify some pointer/struct tests/unit/test-smp-parse: Simplify pointer to compound literal use tests/unit/test-smp-parse: Add 'smp-generic-valid' machine type tests/unit/test-smp-parse: Add 'smp-generic-invalid' machine type tests/unit/test-smp-parse: Add 'smp-with-dies' machine type tests/unit/test-smp-parse: Split the 'generic' test in valid / invalid tests/unit/test-smp-parse: Pass machine type as argument to tests hw/qdev: Rename qdev_connect_gpio_out*() 'input_pin' parameter hw/qdev: Correct qdev_connect_gpio_out_named() documentation hw/qdev: Correct qdev_init_gpio_out_named() documentation hw/qdev: Cosmetic around documentation Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/core/gpio.c13
-rw-r--r--hw/core/machine-smp.c32
-rw-r--r--hw/core/machine.c5
3 files changed, 34 insertions, 16 deletions
diff --git a/hw/core/gpio.c b/hw/core/gpio.c
index 8e6b4f5..80d07a6 100644
--- a/hw/core/gpio.c
+++ b/hw/core/gpio.c
@@ -115,17 +115,18 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
}
void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
- qemu_irq pin)
+ qemu_irq input_pin)
{
char *propname = g_strdup_printf("%s[%d]",
name ? name : "unnamed-gpio-out", n);
- if (pin && !OBJECT(pin)->parent) {
+ if (input_pin && !OBJECT(input_pin)->parent) {
/* We need a name for object_property_set_link to work */
object_property_add_child(container_get(qdev_get_machine(),
"/unattached"),
- "non-qdev-gpio[*]", OBJECT(pin));
+ "non-qdev-gpio[*]", OBJECT(input_pin));
}
- object_property_set_link(OBJECT(dev), propname, OBJECT(pin), &error_abort);
+ object_property_set_link(OBJECT(dev), propname,
+ OBJECT(input_pin), &error_abort);
g_free(propname);
}
@@ -165,9 +166,9 @@ qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
return disconnected;
}
-void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin)
+void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq input_pin)
{
- qdev_connect_gpio_out_named(dev, NULL, n, pin);
+ qdev_connect_gpio_out_named(dev, NULL, n, input_pin);
}
void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c
index 116a0cb..b39ed21 100644
--- a/hw/core/machine-smp.c
+++ b/hw/core/machine-smp.c
@@ -37,6 +37,10 @@ static char *cpu_hierarchy_to_string(MachineState *ms)
g_string_append_printf(s, " * dies (%u)", ms->smp.dies);
}
+ if (mc->smp_props.clusters_supported) {
+ g_string_append_printf(s, " * clusters (%u)", ms->smp.clusters);
+ }
+
g_string_append_printf(s, " * cores (%u)", ms->smp.cores);
g_string_append_printf(s, " * threads (%u)", ms->smp.threads);
@@ -44,7 +48,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms)
}
/*
- * smp_parse - Generic function used to parse the given SMP configuration
+ * machine_parse_smp_config: Generic function used to parse the given
+ * SMP configuration
*
* Any missing parameter in "cpus/maxcpus/sockets/cores/threads" will be
* automatically computed based on the provided ones.
@@ -63,12 +68,14 @@ static char *cpu_hierarchy_to_string(MachineState *ms)
* introduced topology members which are likely to be target specific should
* be directly set as 1 if they are omitted (e.g. dies for PC since 4.1).
*/
-void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
+void machine_parse_smp_config(MachineState *ms,
+ const SMPConfiguration *config, Error **errp)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
unsigned cpus = config->has_cpus ? config->cpus : 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;
unsigned cores = config->has_cores ? config->cores : 0;
unsigned threads = config->has_threads ? config->threads : 0;
unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0;
@@ -80,6 +87,7 @@ void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
if ((config->has_cpus && config->cpus == 0) ||
(config->has_sockets && config->sockets == 0) ||
(config->has_dies && config->dies == 0) ||
+ (config->has_clusters && config->clusters == 0) ||
(config->has_cores && config->cores == 0) ||
(config->has_threads && config->threads == 0) ||
(config->has_maxcpus && config->maxcpus == 0)) {
@@ -95,8 +103,13 @@ void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
error_setg(errp, "dies not supported by this machine's CPU topology");
return;
}
+ if (!mc->smp_props.clusters_supported && clusters > 1) {
+ error_setg(errp, "clusters not supported by this machine's CPU topology");
+ return;
+ }
dies = dies > 0 ? dies : 1;
+ clusters = clusters > 0 ? clusters : 1;
/* compute missing values based on the provided ones */
if (cpus == 0 && maxcpus == 0) {
@@ -111,41 +124,42 @@ void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp)
if (sockets == 0) {
cores = cores > 0 ? cores : 1;
threads = threads > 0 ? threads : 1;
- sockets = maxcpus / (dies * cores * threads);
+ sockets = maxcpus / (dies * clusters * cores * threads);
} else if (cores == 0) {
threads = threads > 0 ? threads : 1;
- cores = maxcpus / (sockets * dies * threads);
+ cores = maxcpus / (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 * threads);
+ cores = maxcpus / (sockets * dies * clusters * threads);
} else if (sockets == 0) {
threads = threads > 0 ? threads : 1;
- sockets = maxcpus / (dies * cores * threads);
+ sockets = maxcpus / (dies * clusters * cores * threads);
}
}
/* try to calculate omitted threads at last */
if (threads == 0) {
- threads = maxcpus / (sockets * dies * cores);
+ threads = maxcpus / (sockets * dies * clusters * cores);
}
}
- maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads;
+ maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * clusters * cores * threads;
cpus = cpus > 0 ? cpus : maxcpus;
ms->smp.cpus = cpus;
ms->smp.sockets = sockets;
ms->smp.dies = dies;
+ ms->smp.clusters = clusters;
ms->smp.cores = cores;
ms->smp.threads = threads;
ms->smp.max_cpus = maxcpus;
/* sanity-check of the computed topology */
- if (sockets * dies * cores * threads != maxcpus) {
+ if (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 53a99ab..a4a2df4 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -742,10 +742,12 @@ static void machine_get_smp(Object *obj, Visitor *v, const char *name,
.has_cpus = true, .cpus = ms->smp.cpus,
.has_sockets = true, .sockets = ms->smp.sockets,
.has_dies = true, .dies = ms->smp.dies,
+ .has_clusters = true, .clusters = ms->smp.clusters,
.has_cores = true, .cores = ms->smp.cores,
.has_threads = true, .threads = ms->smp.threads,
.has_maxcpus = true, .maxcpus = ms->smp.max_cpus,
};
+
if (!visit_type_SMPConfiguration(v, name, &config, &error_abort)) {
return;
}
@@ -761,7 +763,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name,
return;
}
- smp_parse(ms, config, errp);
+ machine_parse_smp_config(ms, config, errp);
}
static void machine_class_init(ObjectClass *oc, void *data)
@@ -932,6 +934,7 @@ static void machine_initfn(Object *obj)
ms->smp.max_cpus = mc->default_cpus;
ms->smp.sockets = 1;
ms->smp.dies = 1;
+ ms->smp.clusters = 1;
ms->smp.cores = 1;
ms->smp.threads = 1;
}