diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-12-31 09:33:56 -0800 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-12-31 09:33:56 -0800 |
commit | 814a0505302d6af277557f10f88d3639eff7a547 (patch) | |
tree | b40e7bf8b74a28bfe03e5b9cf66cec5244a22f36 /hw | |
parent | 69f153667fce723ee546d2f047d66d0cfa67c3cc (diff) | |
parent | 2ece6e64846e1929c4ed338c73328d3b126e48d3 (diff) | |
download | qemu-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.c | 13 | ||||
-rw-r--r-- | hw/core/machine-smp.c | 32 | ||||
-rw-r--r-- | hw/core/machine.c | 5 |
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; } |