From 236e9397b320518372a67c55777193c032b93d89 Mon Sep 17 00:00:00 2001 From: Maksim Davydov Date: Tue, 19 Mar 2024 00:35:48 +0300 Subject: qmp: add dump machine type compatibility properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To control that creating new machine type doesn't affect the previous types (their compat_props) and to check complex compat_props inheritance we need qmp command to print machine type compatibility properties. This patch adds the ability to get list of all the compat_props of the corresponding supported machines for their comparison via new optional argument of "query-machines" command. Since information on compatibility properties can increase the command output by a factor of 40, add an argument to enable it, default off. Signed-off-by: Maksim Davydov Reviewed-by: Vladimir Sementsov-Ogievskiy Acked-by: Markus Armbruster Message-ID: <20240318213550.155573-3-davydov-max@yandex-team.ru> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine-qmp-cmds.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'hw/core') diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index c20829b..5972100 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -64,7 +64,8 @@ CpuInfoFastList *qmp_query_cpus_fast(Error **errp) return head; } -MachineInfoList *qmp_query_machines(Error **errp) +MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props, + Error **errp) { GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); MachineInfoList *mach_list = NULL; @@ -96,6 +97,26 @@ MachineInfoList *qmp_query_machines(Error **errp) info->default_ram_id = g_strdup(mc->default_ram_id); } + if (compat_props && mc->compat_props) { + int i; + info->compat_props = NULL; + CompatPropertyList **tail = &(info->compat_props); + info->has_compat_props = true; + + for (i = 0; i < mc->compat_props->len; i++) { + GlobalProperty *mt_prop = g_ptr_array_index(mc->compat_props, + i); + CompatProperty *prop; + + prop = g_malloc0(sizeof(*prop)); + prop->qom_type = g_strdup(mt_prop->driver); + prop->property = g_strdup(mt_prop->property); + prop->value = g_strdup(mt_prop->value); + + QAPI_LIST_APPEND(tail, prop); + } + } + QAPI_LIST_PREPEND(mach_list, info); } -- cgit v1.1 From 159fb790e48992f74644b0b0876615e8caacbfe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 18 Apr 2024 16:49:16 +0200 Subject: hw/elf_ops: Rename elf_ops.h -> elf_ops.h.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 139c1837db ("meson: rename included C source files to .c.inc"), QEMU standard procedure for included C files is to use *.c.inc. Besides, since commit 6a0057aa22 ("docs/devel: make a statement about includes") this is documented in the Coding Style: If you do use template header files they should be named with the ``.c.inc`` or ``.h.inc`` suffix to make it clear they are being included for expansion. Therefore rename "hw/elf_ops.h" as "hw/elf_ops.h.inc". Signed-off-by: Philippe Mathieu-Daudé Acked-by: Richard Henderson Message-Id: <20240424173333.96148-2-philmd@linaro.org> --- hw/core/loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/core') diff --git a/hw/core/loader.c b/hw/core/loader.c index b8e52f3..2f8105d 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -305,7 +305,7 @@ static void *load_at(int fd, off_t offset, size_t size) #define elf_word uint32_t #define elf_sword int32_t #define bswapSZs bswap32s -#include "hw/elf_ops.h" +#include "hw/elf_ops.h.inc" #undef elfhdr #undef elf_phdr @@ -327,7 +327,7 @@ static void *load_at(int fd, off_t offset, size_t size) #define elf_sword int64_t #define bswapSZs bswap64s #define SZ 64 -#include "hw/elf_ops.h" +#include "hw/elf_ops.h.inc" const char *load_elf_strerror(ssize_t error) { -- cgit v1.1 From dcba73b4453b7ed74d2ae24c5c8b273431c4484c Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 24 Apr 2024 23:49:09 +0800 Subject: hw/core/machine: Introduce the module as a CPU topology level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In x86, module is the topology level above core, which contains a set of cores that share certain resources (in current products, the resource usually includes L2 cache, as well as module scoped features and MSRs). Though smp.clusters could also share the L2 cache resource [1], there are following reasons that drive us to introduce the new smp.modules: * As the CPU topology abstraction in device tree [2], cluster supports nesting (though currently QEMU hasn't support that). In contrast, (x86) module does not support nesting. * Due to nesting, there is great flexibility in sharing resources on cluster, rather than narrowing cluster down to sharing L2 (and L3 tags) as the lowest topology level that contains cores. * Flexible nesting of cluster allows it to correspond to any level between the x86 package and core. * In Linux kernel, x86's cluster only represents the L2 cache domain but QEMU's smp.clusters is the CPU topology level. Linux kernel will also expose module level topology information in sysfs for x86. To avoid cluster ambiguity and keep a consistent CPU topology naming style with the Linux kernel, we introduce module level for x86. The module is, in existing hardware practice, the lowest layer that contains the core, while the cluster is able to have a higher topological scope than the module due to its nesting. Therefore, place the module between the cluster and the core: drawer/book/socket/die/cluster/module/core/thread With the above topological hierarchy order, introduce module level support in MachineState and MachineClass. [1]: https://lore.kernel.org/qemu-devel/c3d68005-54e0-b8fe-8dc1-5989fe3c7e69@huawei.com/ [2]: https://www.kernel.org/doc/Documentation/devicetree/bindings/cpu/cpu-topology.txt Suggested-by: Xiaoyao Li Tested-by: Yongwei Ma Signed-off-by: Zhao Liu Tested-by: Babu Moger Message-ID: <20240424154929.1487382-2-zhao1.liu@intel.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine-smp.c | 2 +- hw/core/machine.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'hw/core') diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index 27864c9..2e68fcf 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -266,7 +266,7 @@ void machine_parse_smp_config(MachineState *ms, unsigned int machine_topo_get_cores_per_socket(const MachineState *ms) { - return ms->smp.cores * ms->smp.clusters * ms->smp.dies; + return ms->smp.cores * ms->smp.modules * ms->smp.clusters * ms->smp.dies; } unsigned int machine_topo_get_threads_per_socket(const MachineState *ms) diff --git a/hw/core/machine.c b/hw/core/machine.c index 582c2df..9966641 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1157,6 +1157,7 @@ static void machine_initfn(Object *obj) ms->smp.sockets = 1; ms->smp.dies = 1; ms->smp.clusters = 1; + ms->smp.modules = 1; ms->smp.cores = 1; ms->smp.threads = 1; -- cgit v1.1 From 8ec0a46347987c74464fe67c42030d074fe8c0f0 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 24 Apr 2024 23:49:10 +0800 Subject: hw/core/machine: Support modules in -smp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add "modules" parameter parsing support in -smp. Suggested-by: Xiaoyao Li Tested-by: Yongwei Ma Signed-off-by: Zhao Liu Tested-by: Babu Moger Acked-by: Markus Armbruster Message-ID: <20240424154929.1487382-3-zhao1.liu@intel.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine-smp.c | 39 +++++++++++++++++++++++++++++++++------ hw/core/machine.c | 1 + 2 files changed, 34 insertions(+), 6 deletions(-) (limited to 'hw/core') diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index 2e68fcf..2b93fa9 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -51,6 +51,10 @@ static char *cpu_hierarchy_to_string(MachineState *ms) g_string_append_printf(s, " * clusters (%u)", ms->smp.clusters); } + if (mc->smp_props.modules_supported) { + g_string_append_printf(s, " * modules (%u)", ms->smp.modules); + } + g_string_append_printf(s, " * cores (%u)", ms->smp.cores); g_string_append_printf(s, " * threads (%u)", ms->smp.threads); @@ -88,6 +92,7 @@ void machine_parse_smp_config(MachineState *ms, 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 modules = config->has_modules ? config->modules : 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; @@ -103,6 +108,7 @@ void machine_parse_smp_config(MachineState *ms, (config->has_sockets && config->sockets == 0) || (config->has_dies && config->dies == 0) || (config->has_clusters && config->clusters == 0) || + (config->has_modules && config->modules == 0) || (config->has_cores && config->cores == 0) || (config->has_threads && config->threads == 0) || (config->has_maxcpus && config->maxcpus == 0)) { @@ -115,6 +121,20 @@ void machine_parse_smp_config(MachineState *ms, * If not supported by the machine, a topology parameter must be * omitted. */ + if (!mc->smp_props.modules_supported && config->has_modules) { + if (config->modules > 1) { + error_setg(errp, "modules not supported by this " + "machine's CPU topology"); + return; + } else { + /* Here modules only equals 1 since we've checked zero case. */ + warn_report("Deprecated CPU topology (considered invalid): " + "Unsupported modules parameter mustn't be " + "specified as 1"); + } + } + modules = modules > 0 ? modules : 1; + if (!mc->smp_props.clusters_supported && config->has_clusters) { if (config->clusters > 1) { error_setg(errp, "clusters not supported by this " @@ -185,11 +205,13 @@ void machine_parse_smp_config(MachineState *ms, cores = cores > 0 ? cores : 1; threads = threads > 0 ? threads : 1; sockets = maxcpus / - (drawers * books * dies * clusters * cores * threads); + (drawers * books * dies * clusters * + modules * cores * threads); } else if (cores == 0) { threads = threads > 0 ? threads : 1; cores = maxcpus / - (drawers * books * sockets * dies * clusters * threads); + (drawers * books * sockets * dies * + clusters * modules * threads); } } else { /* prefer cores over sockets since 6.2 */ @@ -197,22 +219,26 @@ void machine_parse_smp_config(MachineState *ms, sockets = sockets > 0 ? sockets : 1; threads = threads > 0 ? threads : 1; cores = maxcpus / - (drawers * books * sockets * dies * clusters * threads); + (drawers * books * sockets * dies * + clusters * modules * threads); } else if (sockets == 0) { threads = threads > 0 ? threads : 1; sockets = maxcpus / - (drawers * books * dies * clusters * cores * threads); + (drawers * books * dies * clusters * + modules * cores * threads); } } /* try to calculate omitted threads at last */ if (threads == 0) { threads = maxcpus / - (drawers * books * sockets * dies * clusters * cores); + (drawers * books * sockets * dies * + clusters * modules * cores); } } - total_cpus = drawers * books * sockets * dies * clusters * cores * threads; + total_cpus = drawers * books * sockets * dies * + clusters * modules * cores * threads; maxcpus = maxcpus > 0 ? maxcpus : total_cpus; cpus = cpus > 0 ? cpus : maxcpus; @@ -222,6 +248,7 @@ void machine_parse_smp_config(MachineState *ms, ms->smp.sockets = sockets; ms->smp.dies = dies; ms->smp.clusters = clusters; + ms->smp.modules = modules; ms->smp.cores = cores; ms->smp.threads = threads; ms->smp.max_cpus = maxcpus; diff --git a/hw/core/machine.c b/hw/core/machine.c index 9966641..494b712 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -881,6 +881,7 @@ static void machine_get_smp(Object *obj, Visitor *v, const char *name, .has_sockets = true, .sockets = ms->smp.sockets, .has_dies = true, .dies = ms->smp.dies, .has_clusters = true, .clusters = ms->smp.clusters, + .has_modules = true, .modules = ms->smp.modules, .has_cores = true, .cores = ms->smp.cores, .has_threads = true, .threads = ms->smp.threads, .has_maxcpus = true, .maxcpus = ms->smp.max_cpus, -- cgit v1.1 From 989bb312b021d66927db8e5f443503d63722b38d Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 24 Apr 2024 23:49:11 +0800 Subject: hw/core: Introduce module-id as the topology subindex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add module-id in CpuInstanceProperties, to locate the CPU with module level. Suggested-by: Xiaoyao Li Tested-by: Yongwei Ma Signed-off-by: Zhao Liu Tested-by: Babu Moger Acked-by: Markus Armbruster Message-ID: <20240424154929.1487382-4-zhao1.liu@intel.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine-hmp-cmds.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'hw/core') diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c index a6ff6a4..8701f00 100644 --- a/hw/core/machine-hmp-cmds.c +++ b/hw/core/machine-hmp-cmds.c @@ -87,6 +87,10 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n", c->cluster_id); } + if (c->has_module_id) { + monitor_printf(mon, " module-id: \"%" PRIu64 "\"\n", + c->module_id); + } if (c->has_core_id) { monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); } -- cgit v1.1 From 098de99aad1aa911b4950b47b55d2e2bcc4f9c0c Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 24 Apr 2024 23:49:12 +0800 Subject: hw/core: Support module-id in numa configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Module is a level above the core, thereby supporting numa configuration on the module level can bring user more numa flexibility. This is the natural further support for module level. Add module level support in numa configuration. Tested-by: Yongwei Ma Signed-off-by: Zhao Liu Tested-by: Babu Moger Message-ID: <20240424154929.1487382-5-zhao1.liu@intel.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/machine.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'hw/core') diff --git a/hw/core/machine.c b/hw/core/machine.c index 494b712..0dec48e 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -800,6 +800,11 @@ void machine_set_cpu_numa_node(MachineState *machine, return; } + if (props->has_module_id && !slot->props.has_module_id) { + error_setg(errp, "module-id is not supported"); + return; + } + if (props->has_cluster_id && !slot->props.has_cluster_id) { error_setg(errp, "cluster-id is not supported"); return; @@ -824,6 +829,11 @@ void machine_set_cpu_numa_node(MachineState *machine, continue; } + if (props->has_module_id && + props->module_id != slot->props.module_id) { + continue; + } + if (props->has_cluster_id && props->cluster_id != slot->props.cluster_id) { continue; @@ -1226,6 +1236,12 @@ static char *cpu_slot_to_string(const CPUArchId *cpu) } g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id); } + if (cpu->props.has_module_id) { + if (s->len) { + g_string_append_printf(s, ", "); + } + g_string_append_printf(s, "module-id: %"PRId64, cpu->props.module_id); + } if (cpu->props.has_core_id) { if (s->len) { g_string_append_printf(s, ", "); -- cgit v1.1