From 94aae6ed218e962095bfe37efe5ae5ca6f30d9a2 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:18 +0800 Subject: tests/unit/test-smp-parse: Fix comments of drawers and books case Fix the comments to match the actual configurations. Signed-off-by: Zhao Liu Reviewed-by: Thomas Huth Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-2-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 9fdba24fce..fa8e7d83a7 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -474,8 +474,8 @@ static const struct SMPTestData data_with_drawers_invalid[] = { static const struct SMPTestData data_with_drawers_books_invalid[] = { { /* - * config: -smp 200,drawers=2,books=2,sockets=2,cores=4,\ - * threads=2,maxcpus=200 + * config: -smp 200,drawers=3,books=5,sockets=2,cores=4,\ + * threads=2,maxcpus=200 */ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 200, T, 3, T, 5, T, 2, T, 4, T, 2, T, 200), @@ -485,8 +485,8 @@ static const struct SMPTestData data_with_drawers_books_invalid[] = { "cores (4) * threads (2) != maxcpus (200)", }, { /* - * config: -smp 242,drawers=2,books=2,sockets=2,cores=4,\ - * threads=2,maxcpus=240 + * config: -smp 242,drawers=3,books=5,sockets=2,cores=4,\ + * threads=2,maxcpus=240 */ .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 242, T, 3, T, 5, T, 2, T, 4, T, 2, T, 240), -- cgit 1.4.1 From 7c56fb74b31fa697c7cdf634a141756b98771f08 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:19 +0800 Subject: tests/unit/test-smp-parse: Fix comment of parameters=1 case SMP_CONFIG_WITH_FULL_TOPO hasn't support module level, so the parameter should indicate the "clusters". Additionally, reorder the parameters of -smp to match the topology hierarchy order. Signed-off-by: Zhao Liu Reviewed-by: Thomas Huth Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-3-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index fa8e7d83a7..c9cbc89c21 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -333,7 +333,9 @@ static const struct SMPTestData data_generic_valid[] = { }, { /* * Unsupported parameters are always allowed to be set to '1' - * config: -smp 8,books=1,drawers=1,sockets=2,modules=1,dies=1,cores=2,threads=2,maxcpus=8 + * config: + * -smp 8,drawers=1,books=1,sockets=2,dies=1,clusters=1,cores=2,\ + * threads=2,maxcpus=8 * expect: cpus=8,sockets=2,cores=2,threads=2,maxcpus=8 */ .config = SMP_CONFIG_WITH_FULL_TOPO(8, 1, 1, 2, 1, 1, 2, 2, 8), .expect_prefer_sockets = CPU_TOPOLOGY_GENERIC(8, 2, 2, 2, 8), -- cgit 1.4.1 From 74c3d84d48084be058e5a9f9aa21f9edf174540e Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:20 +0800 Subject: tests/unit/test-smp-parse: Fix an invalid topology case Adjust the "cpus" parameter to match the comment configuration. Signed-off-by: Zhao Liu Reviewed-by: Thomas Huth Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-4-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index c9cbc89c21..5d99e0d923 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -528,7 +528,7 @@ static const struct SMPTestData data_full_topo_invalid[] = { * config: -smp 1,drawers=3,books=5,sockets=2,dies=4,\ * clusters=2,cores=7,threads=3,maxcpus=5040 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(3361, 3, 5, 2, 4, 2, 7, 3, 5040), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 3, 5, 2, 4, 2, 7, 3, 5040), .expect_error = "Invalid SMP CPUs 5040. The max CPUs supported " "by machine '" SMP_MACHINE_NAME "' is 4096", }, -- cgit 1.4.1 From aedfeffe19e65a657a4d989593fcf233809127d8 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:21 +0800 Subject: tests/unit/test-smp-parse: Use default parameters=0 when not set in -smp Since -smp allows parameters=1 whether the level is supported by machine, to avoid the test scenarios where the parameter defaults to 1 cause some errors to be masked, explicitly set undesired parameters to 0. Signed-off-by: Zhao Liu Reviewed-by: Thomas Huth Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-5-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 5d99e0d923..e3a0a9d12d 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -436,7 +436,7 @@ static const struct SMPTestData data_with_clusters_invalid[] = { static const struct SMPTestData data_with_books_invalid[] = { { /* config: -smp 16,books=2,sockets=2,cores=4,threads=2,maxcpus=16 */ - .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 16, F, 1, T, 2, T, + .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 16, F, 0, T, 2, T, 2, T, 4, T, 2, T, 16), .expect_error = "Invalid CPU topology: " "product of the hierarchy must match maxcpus: " @@ -444,7 +444,7 @@ static const struct SMPTestData data_with_books_invalid[] = { "!= maxcpus (16)", }, { /* config: -smp 34,books=2,sockets=2,cores=4,threads=2,maxcpus=32 */ - .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 34, F, 1, T, 2, T, + .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 34, F, 0, T, 2, T, 2, T, 4, T, 2, T, 32), .expect_error = "Invalid CPU topology: " "maxcpus must be equal to or greater than smp: " @@ -456,7 +456,7 @@ static const struct SMPTestData data_with_books_invalid[] = { static const struct SMPTestData data_with_drawers_invalid[] = { { /* config: -smp 16,drawers=2,sockets=2,cores=4,threads=2,maxcpus=16 */ - .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 16, T, 2, F, 1, T, + .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 16, T, 2, F, 0, T, 2, T, 4, T, 2, T, 16), .expect_error = "Invalid CPU topology: " "product of the hierarchy must match maxcpus: " @@ -464,7 +464,7 @@ static const struct SMPTestData data_with_drawers_invalid[] = { "!= maxcpus (16)", }, { /* config: -smp 34,drawers=2,sockets=2,cores=4,threads=2,maxcpus=32 */ - .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 34, T, 2, F, 1, T, + .config = SMP_CONFIG_WITH_BOOKS_DRAWERS(T, 34, T, 2, F, 0, T, 2, T, 4, T, 2, T, 32), .expect_error = "Invalid CPU topology: " "maxcpus must be equal to or greater than smp: " -- cgit 1.4.1 From b985f4be53fe40e10583c3d35ff05255d712686a Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:22 +0800 Subject: tests/unit/test-smp-parse: Make test cases aware of module level Currently, -smp supports module level. It is necessary to consider the effects of module in the test cases to ensure that the calculations are correct. This is also the preparation to add module test cases. Signed-off-by: Zhao Liu Reviewed-by: Thomas Huth Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-6-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index e3a0a9d12d..2214e47ba9 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -629,6 +629,7 @@ static char *smp_config_to_string(const SMPConfiguration *config) " .has_sockets = %5s, sockets = %" PRId64 ",\n" " .has_dies = %5s, dies = %" PRId64 ",\n" " .has_clusters = %5s, clusters = %" PRId64 ",\n" + " .has_modules = %5s, modules = %" PRId64 ",\n" " .has_cores = %5s, cores = %" PRId64 ",\n" " .has_threads = %5s, threads = %" PRId64 ",\n" " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n" @@ -639,6 +640,7 @@ static char *smp_config_to_string(const SMPConfiguration *config) config->has_sockets ? "true" : "false", config->sockets, config->has_dies ? "true" : "false", config->dies, config->has_clusters ? "true" : "false", config->clusters, + config->has_modules ? "true" : "false", config->modules, config->has_cores ? "true" : "false", config->cores, config->has_threads ? "true" : "false", config->threads, config->has_maxcpus ? "true" : "false", config->maxcpus); @@ -679,6 +681,7 @@ static char *cpu_topology_to_string(const CpuTopology *topo, " .sockets = %u,\n" " .dies = %u,\n" " .clusters = %u,\n" + " .modules = %u,\n" " .cores = %u,\n" " .threads = %u,\n" " .max_cpus = %u,\n" @@ -688,8 +691,8 @@ static char *cpu_topology_to_string(const CpuTopology *topo, "}", topo->cpus, topo->drawers, topo->books, topo->sockets, topo->dies, topo->clusters, - topo->cores, topo->threads, topo->max_cpus, - threads_per_socket, cores_per_socket, + topo->modules, topo->cores, topo->threads, + topo->max_cpus, threads_per_socket, cores_per_socket, has_clusters ? "true" : "false"); } @@ -732,6 +735,7 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config, (ms->smp.sockets == expect_topo->sockets) && (ms->smp.dies == expect_topo->dies) && (ms->smp.clusters == expect_topo->clusters) && + (ms->smp.modules == expect_topo->modules) && (ms->smp.cores == expect_topo->cores) && (ms->smp.threads == expect_topo->threads) && (ms->smp.max_cpus == expect_topo->max_cpus) && @@ -812,6 +816,11 @@ static void smp_parse_test(MachineState *ms, SMPTestData *data, bool is_valid) /* The parsed results of the unsupported parameters should be 1 */ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data) { + if (!mc->smp_props.modules_supported) { + data->expect_prefer_sockets.modules = 1; + data->expect_prefer_cores.modules = 1; + } + if (!mc->smp_props.dies_supported) { data->expect_prefer_sockets.dies = 1; data->expect_prefer_cores.dies = 1; -- cgit 1.4.1 From a05ed358542b90a3d53d96108fe5b83c545dfb84 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:23 +0800 Subject: tests/unit/test-smp-parse: Test "modules" parameter in -smp Cover the module cases in test-smp-parse. Signed-off-by: Zhao Liu Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-7-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 112 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 9 deletions(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 2214e47ba9..01832e5eda 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -48,17 +48,19 @@ } /* - * Currently a 4-level topology hierarchy is supported on PC machines - * -sockets/dies/cores/threads + * Currently a 5-level topology hierarchy is supported on PC machines + * -sockets/dies/modules/cores/threads */ -#define SMP_CONFIG_WITH_DIES(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \ +#define SMP_CONFIG_WITH_MODS_DIES(ha, a, hb, b, hc, c, hd, d, \ + he, e, hf, f, hg, g) \ { \ .has_cpus = ha, .cpus = a, \ .has_sockets = hb, .sockets = b, \ .has_dies = hc, .dies = c, \ - .has_cores = hd, .cores = d, \ - .has_threads = he, .threads = e, \ - .has_maxcpus = hf, .maxcpus = f, \ + .has_modules = hd, .modules = d, \ + .has_cores = he, .cores = e, \ + .has_threads = hf, .threads = f, \ + .has_maxcpus = hg, .maxcpus = g, \ } /* @@ -345,8 +347,14 @@ static const struct SMPTestData data_generic_valid[] = { static const struct SMPTestData data_generic_invalid[] = { { + /* config: -smp 2,modules=2 */ + .config = SMP_CONFIG_WITH_MODS_DIES(T, 2, F, 0, F, 0, T, 2, + F, 0, F, 0, F, 0), + .expect_error = "modules > 1 not supported by this machine's CPU topology", + }, { /* config: -smp 2,dies=2 */ - .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), + .config = SMP_CONFIG_WITH_MODS_DIES(T, 2, F, 0, T, 2, F, 0, + F, 0, F, 0, F, 0), .expect_error = "dies > 1 not supported by this machine's CPU topology", }, { /* config: -smp 2,clusters=2 */ @@ -397,17 +405,39 @@ static const struct SMPTestData data_generic_invalid[] = { }, }; +static const struct SMPTestData data_with_modules_invalid[] = { + { + /* config: -smp 16,sockets=2,modules=2,cores=4,threads=2,maxcpus=16 */ + .config = SMP_CONFIG_WITH_MODS_DIES(T, 16, T, 2, F, 0, T, 2, + T, 4, T, 2, T, 16), + .expect_error = "Invalid CPU topology: " + "product of the hierarchy must match maxcpus: " + "sockets (2) * modules (2) * cores (4) * threads (2) " + "!= maxcpus (16)", + }, { + /* config: -smp 34,sockets=2,modules=2,cores=4,threads=2,maxcpus=32 */ + .config = SMP_CONFIG_WITH_MODS_DIES(T, 34, T, 2, F, 0, T, 2, + T, 4, T, 2, T, 32), + .expect_error = "Invalid CPU topology: " + "maxcpus must be equal to or greater than smp: " + "sockets (2) * modules (2) * cores (4) * threads (2) " + "== maxcpus (32) < smp_cpus (34)", + }, +}; + static const struct SMPTestData data_with_dies_invalid[] = { { /* config: -smp 16,sockets=2,dies=2,cores=4,threads=2,maxcpus=16 */ - .config = SMP_CONFIG_WITH_DIES(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16), + .config = SMP_CONFIG_WITH_MODS_DIES(T, 16, T, 2, T, 2, F, 0, + T, 4, T, 2, T, 16), .expect_error = "Invalid CPU topology: " "product of the hierarchy must match maxcpus: " "sockets (2) * dies (2) * cores (4) * threads (2) " "!= maxcpus (16)", }, { /* config: -smp 34,sockets=2,dies=2,cores=4,threads=2,maxcpus=32 */ - .config = SMP_CONFIG_WITH_DIES(T, 34, T, 2, T, 2, T, 4, T, 2, T, 32), + .config = SMP_CONFIG_WITH_MODS_DIES(T, 34, T, 2, T, 2, F, 0, + T, 4, T, 2, T, 32), .expect_error = "Invalid CPU topology: " "maxcpus must be equal to or greater than smp: " "sockets (2) * dies (2) * cores (4) * threads (2) " @@ -861,6 +891,13 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) mc->max_cpus = MAX_CPUS - 1; } +static void machine_with_modules_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->smp_props.modules_supported = true; +} + static void machine_with_dies_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -945,6 +982,56 @@ static void test_generic_invalid(const void *opaque) object_unref(obj); } +static void test_with_modules(const void *opaque) +{ + const char *machine_type = opaque; + Object *obj = object_new(machine_type); + MachineState *ms = MACHINE(obj); + MachineClass *mc = MACHINE_GET_CLASS(obj); + SMPTestData data = {}; + unsigned int num_modules = 2; + int i; + + for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { + data = data_generic_valid[i]; + unsupported_params_init(mc, &data); + + /* when modules parameter is omitted, it will be set as 1 */ + data.expect_prefer_sockets.modules = 1; + data.expect_prefer_cores.modules = 1; + + smp_parse_test(ms, &data, true); + + /* when modules parameter is specified */ + data.config.has_modules = true; + data.config.modules = num_modules; + if (data.config.has_cpus) { + data.config.cpus *= num_modules; + } + if (data.config.has_maxcpus) { + data.config.maxcpus *= num_modules; + } + + data.expect_prefer_sockets.modules = num_modules; + data.expect_prefer_sockets.cpus *= num_modules; + data.expect_prefer_sockets.max_cpus *= num_modules; + data.expect_prefer_cores.modules = num_modules; + data.expect_prefer_cores.cpus *= num_modules; + data.expect_prefer_cores.max_cpus *= num_modules; + + smp_parse_test(ms, &data, true); + } + + for (i = 0; i < ARRAY_SIZE(data_with_modules_invalid); i++) { + data = data_with_modules_invalid[i]; + unsupported_params_init(mc, &data); + + smp_parse_test(ms, &data, false); + } + + object_unref(obj); +} + static void test_with_dies(const void *opaque) { const char *machine_type = opaque; @@ -1303,6 +1390,10 @@ static const TypeInfo smp_machine_types[] = { .name = MACHINE_TYPE_NAME("smp-generic-invalid"), .parent = TYPE_MACHINE, .class_init = machine_generic_invalid_class_init, + }, { + .name = MACHINE_TYPE_NAME("smp-with-modules"), + .parent = TYPE_MACHINE, + .class_init = machine_with_modules_class_init, }, { .name = MACHINE_TYPE_NAME("smp-with-dies"), .parent = TYPE_MACHINE, @@ -1344,6 +1435,9 @@ int main(int argc, char *argv[]) g_test_add_data_func("/test-smp-parse/generic/invalid", MACHINE_TYPE_NAME("smp-generic-invalid"), test_generic_invalid); + g_test_add_data_func("/test-smp-parse/with_modules", + MACHINE_TYPE_NAME("smp-with-modules"), + test_with_modules); g_test_add_data_func("/test-smp-parse/with_dies", MACHINE_TYPE_NAME("smp-with-dies"), test_with_dies); -- cgit 1.4.1 From fe4b99525ac669ce9c57af19a7b9a87ebeb68866 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:24 +0800 Subject: tests/unit/test-smp-parse: Test "modules" and "dies" combination case Since i386 PC machine supports both "modules" and "dies" in -smp, add the "modules" and "dies" combination test case to match the actual topology usage scenario. Signed-off-by: Zhao Liu Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-8-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 103 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 01832e5eda..2ca8530e93 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -445,6 +445,33 @@ static const struct SMPTestData data_with_dies_invalid[] = { }, }; +static const struct SMPTestData data_with_modules_dies_invalid[] = { + { + /* + * config: -smp 200,sockets=3,dies=5,modules=2,cores=4,\ + * threads=2,maxcpus=200 + */ + .config = SMP_CONFIG_WITH_MODS_DIES(T, 200, T, 3, T, 5, T, + 2, T, 4, T, 2, T, 200), + .expect_error = "Invalid CPU topology: " + "product of the hierarchy must match maxcpus: " + "sockets (3) * dies (5) * modules (2) * " + "cores (4) * threads (2) != maxcpus (200)", + }, { + /* + * config: -smp 242,sockets=3,dies=5,modules=2,cores=4,\ + * threads=2,maxcpus=240 + */ + .config = SMP_CONFIG_WITH_MODS_DIES(T, 242, T, 3, T, 5, T, + 2, T, 4, T, 2, T, 240), + .expect_error = "Invalid CPU topology: " + "maxcpus must be equal to or greater than smp: " + "sockets (3) * dies (5) * modules (2) * " + "cores (4) * threads (2) " + "== maxcpus (240) < smp_cpus (242)", + }, +}; + static const struct SMPTestData data_with_clusters_invalid[] = { { /* config: -smp 16,sockets=2,clusters=2,cores=4,threads=2,maxcpus=16 */ @@ -905,6 +932,14 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) mc->smp_props.dies_supported = true; } +static void machine_with_modules_dies_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->smp_props.modules_supported = true; + mc->smp_props.dies_supported = true; +} + static void machine_with_clusters_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1082,6 +1117,67 @@ static void test_with_dies(const void *opaque) object_unref(obj); } +static void test_with_modules_dies(const void *opaque) +{ + const char *machine_type = opaque; + Object *obj = object_new(machine_type); + MachineState *ms = MACHINE(obj); + MachineClass *mc = MACHINE_GET_CLASS(obj); + SMPTestData data = {}; + unsigned int num_modules = 5, num_dies = 3; + int i; + + for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { + data = data_generic_valid[i]; + unsupported_params_init(mc, &data); + + /* + * when modules and dies parameters are omitted, they will + * be both set as 1. + */ + data.expect_prefer_sockets.modules = 1; + data.expect_prefer_sockets.dies = 1; + data.expect_prefer_cores.modules = 1; + data.expect_prefer_cores.dies = 1; + + smp_parse_test(ms, &data, true); + + /* when modules and dies parameters are both specified */ + data.config.has_modules = true; + data.config.modules = num_modules; + data.config.has_dies = true; + data.config.dies = num_dies; + + if (data.config.has_cpus) { + data.config.cpus *= num_modules * num_dies; + } + if (data.config.has_maxcpus) { + data.config.maxcpus *= num_modules * num_dies; + } + + data.expect_prefer_sockets.modules = num_modules; + data.expect_prefer_sockets.dies = num_dies; + data.expect_prefer_sockets.cpus *= num_modules * num_dies; + data.expect_prefer_sockets.max_cpus *= num_modules * num_dies; + + data.expect_prefer_cores.modules = num_modules; + data.expect_prefer_cores.dies = num_dies; + data.expect_prefer_cores.cpus *= num_modules * num_dies; + data.expect_prefer_cores.max_cpus *= num_modules * num_dies; + + smp_parse_test(ms, &data, true); + } + + for (i = 0; i < ARRAY_SIZE(data_with_modules_dies_invalid); i++) { + data = data_with_modules_dies_invalid[i]; + unsupported_params_init(mc, &data); + + smp_parse_test(ms, &data, false); + } + + object_unref(obj); +} + static void test_with_clusters(const void *opaque) { const char *machine_type = opaque; @@ -1398,6 +1494,10 @@ static const TypeInfo smp_machine_types[] = { .name = MACHINE_TYPE_NAME("smp-with-dies"), .parent = TYPE_MACHINE, .class_init = machine_with_dies_class_init, + }, { + .name = MACHINE_TYPE_NAME("smp-with-modules-dies"), + .parent = TYPE_MACHINE, + .class_init = machine_with_modules_dies_class_init, }, { .name = MACHINE_TYPE_NAME("smp-with-clusters"), .parent = TYPE_MACHINE, @@ -1441,6 +1541,9 @@ int main(int argc, char *argv[]) g_test_add_data_func("/test-smp-parse/with_dies", MACHINE_TYPE_NAME("smp-with-dies"), test_with_dies); + g_test_add_data_func("/test-smp-parse/with_modules_dies", + MACHINE_TYPE_NAME("smp-with-modules-dies"), + test_with_modules_dies); g_test_add_data_func("/test-smp-parse/with_clusters", MACHINE_TYPE_NAME("smp-with-clusters"), test_with_clusters); -- cgit 1.4.1 From 6a235525d93ae5a35c5006226ffdd7c7de47ba87 Mon Sep 17 00:00:00 2001 From: Zhao Liu Date: Wed, 29 May 2024 14:19:25 +0800 Subject: tests/unit/test-smp-parse: Test the full 8-levels topology hierarchy With module level, QEMU now support 8-levels topology hierarchy. Cover "modules" in SMP_CONFIG_WITH_FULL_TOPO related cases. Signed-off-by: Zhao Liu Tested-by: Yongwei Ma Message-ID: <20240529061925.350323-9-zhao1.liu@intel.com> Signed-off-by: Thomas Huth --- tests/unit/test-smp-parse.c | 129 +++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 44 deletions(-) (limited to 'tests/unit/test-smp-parse.c') diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c index 2ca8530e93..f9bccb56ab 100644 --- a/tests/unit/test-smp-parse.c +++ b/tests/unit/test-smp-parse.c @@ -94,11 +94,11 @@ } /* - * Currently QEMU supports up to a 7-level topology hierarchy, which is the + * Currently QEMU supports up to a 8-level topology hierarchy, which is the * QEMU's unified abstract representation of CPU topology. - * -drawers/books/sockets/dies/clusters/cores/threads + * -drawers/books/sockets/dies/clusters/modules/cores/threads */ -#define SMP_CONFIG_WITH_FULL_TOPO(a, b, c, d, e, f, g, h, i) \ +#define SMP_CONFIG_WITH_FULL_TOPO(a, b, c, d, e, f, g, h, i, j) \ { \ .has_cpus = true, .cpus = a, \ .has_drawers = true, .drawers = b, \ @@ -106,9 +106,10 @@ .has_sockets = true, .sockets = d, \ .has_dies = true, .dies = e, \ .has_clusters = true, .clusters = f, \ - .has_cores = true, .cores = g, \ - .has_threads = true, .threads = h, \ - .has_maxcpus = true, .maxcpus = i, \ + .has_modules = true, .modules = g, \ + .has_cores = true, .cores = h, \ + .has_threads = true, .threads = i, \ + .has_maxcpus = true, .maxcpus = j, \ } /** @@ -336,10 +337,10 @@ static const struct SMPTestData data_generic_valid[] = { /* * Unsupported parameters are always allowed to be set to '1' * config: - * -smp 8,drawers=1,books=1,sockets=2,dies=1,clusters=1,cores=2,\ - * threads=2,maxcpus=8 + * -smp 8,drawers=1,books=1,sockets=2,dies=1,clusters=1,modules=1,\ + * cores=2,threads=2,maxcpus=8 * expect: cpus=8,sockets=2,cores=2,threads=2,maxcpus=8 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(8, 1, 1, 2, 1, 1, 2, 2, 8), + .config = SMP_CONFIG_WITH_FULL_TOPO(8, 1, 1, 2, 1, 1, 1, 2, 2, 8), .expect_prefer_sockets = CPU_TOPOLOGY_GENERIC(8, 2, 2, 2, 8), .expect_prefer_cores = CPU_TOPOLOGY_GENERIC(8, 2, 2, 2, 8), }, @@ -561,32 +562,37 @@ static const struct SMPTestData data_full_topo_invalid[] = { { /* * config: -smp 200,drawers=3,books=5,sockets=2,dies=4,\ - * clusters=2,cores=7,threads=2,maxcpus=200 + * clusters=2,modules=3,cores=7,threads=2,\ + * maxcpus=200 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(200, 3, 5, 2, 4, 2, 7, 2, 200), + .config = SMP_CONFIG_WITH_FULL_TOPO(200, 3, 5, 2, 4, 2, 3, 7, 2, 200), .expect_error = "Invalid CPU topology: " "product of the hierarchy must match maxcpus: " "drawers (3) * books (5) * sockets (2) * dies (4) * " - "clusters (2) * cores (7) * threads (2) " + "clusters (2) * modules (3) * cores (7) * threads (2) " "!= maxcpus (200)", }, { /* - * config: -smp 3361,drawers=3,books=5,sockets=2,dies=4,\ - * clusters=2,cores=7,threads=2,maxcpus=3360 + * config: -smp 2881,drawers=3,books=5,sockets=2,dies=4,\ + * clusters=2,modules=3,cores=2,threads=2, + * maxcpus=2880 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(3361, 3, 5, 2, 4, 2, 7, 2, 3360), + .config = SMP_CONFIG_WITH_FULL_TOPO(2881, 3, 5, 2, 4, + 2, 3, 2, 2, 2880), .expect_error = "Invalid CPU topology: " "maxcpus must be equal to or greater than smp: " - "drawers (3) * books (5) * sockets (2) * dies (4) * " - "clusters (2) * cores (7) * threads (2) " - "== maxcpus (3360) < smp_cpus (3361)", + "drawers (3) * books (5) * sockets (2) * " + "dies (4) * clusters (2) * modules (3) * " + "cores (2) * threads (2) == maxcpus (2880) " + "< smp_cpus (2881)", }, { /* * config: -smp 1,drawers=3,books=5,sockets=2,dies=4,\ - * clusters=2,cores=7,threads=3,maxcpus=5040 + * clusters=2,modules=3,cores=3,threads=3,\ + * maxcpus=6480 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 3, 5, 2, 4, 2, 7, 3, 5040), - .expect_error = "Invalid SMP CPUs 5040. The max CPUs supported " + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 3, 5, 2, 4, 2, 3, 3, 3, 6480), + .expect_error = "Invalid SMP CPUs 6480. The max CPUs supported " "by machine '" SMP_MACHINE_NAME "' is 4096", }, }; @@ -596,81 +602,100 @@ static const struct SMPTestData data_zero_topo_invalid[] = { /* * Test "cpus=0". * config: -smp 0,drawers=1,books=1,sockets=1,dies=1,\ - * clusters=1,cores=1,threads=1,maxcpus=1 + * clusters=1,modules=1,cores=1,threads=1,\ + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(0, 1, 1, 1, 1, 1, 1, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(0, 1, 1, 1, 1, 1, 1, 1, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "drawers=0". * config: -smp 1,drawers=0,books=1,sockets=1,dies=1,\ - * clusters=1,cores=1,threads=1,maxcpus=1 + * clusters=1,modules=1,cores=1,threads=1,\ + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 0, 1, 1, 1, 1, 1, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 0, 1, 1, 1, 1, 1, 1, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "books=0". * config: -smp 1,drawers=1,books=0,sockets=1,dies=1,\ - * clusters=1,cores=1,threads=1,maxcpus=1 + * clusters=1,modules=1,cores=1,threads=1,\ + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 0, 1, 1, 1, 1, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 0, 1, 1, 1, 1, 1, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "sockets=0". * config: -smp 1,drawers=1,books=1,sockets=0,dies=1,\ - * clusters=1,cores=1,threads=1,maxcpus=1 + * clusters=1,modules=1,cores=1,threads=1, + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 0, 1, 1, 1, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 0, 1, 1, 1, 1, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "dies=0". * config: -smp 1,drawers=1,books=1,sockets=1,dies=0,\ - * clusters=1,cores=1,threads=1,maxcpus=1 + * clusters=1,modules=1,cores=1,threads=1,\ + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 0, 1, 1, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 0, 1, 1, 1, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "clusters=0". * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\ - * clusters=0,cores=1,threads=1,maxcpus=1 + * clusters=0,modules=1,cores=1,threads=1,\ + * maxcpus=1 + */ + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 0, 1, 1, 1, 1), + .expect_error = "Invalid CPU topology: CPU topology parameters must " + "be greater than zero", + }, { + /* + * Test "modules=0". + * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\ + * clusters=1,modules=0,cores=1,threads=1,\ + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 0, 1, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 0, 1, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "cores=0". * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\ - * clusters=1,cores=0,threads=1,maxcpus=1 + * clusters=1,modules=1,cores=0,threads=1, + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 0, 1, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 0, 1, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "threads=0". * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\ - * clusters=1,cores=1,threads=0,maxcpus=1 + * clusters=1,modules=1,cores=1,threads=0,\ + * maxcpus=1 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 0, 1), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 1, 0, 1), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, { /* * Test "maxcpus=0". * config: -smp 1,drawers=1,books=1,sockets=1,dies=1,\ - * clusters=1,cores=1,threads=1,maxcpus=0 + * clusters=1,modules=1,cores=1,threads=1,\ + * maxcpus=0 */ - .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 1, 0), + .config = SMP_CONFIG_WITH_FULL_TOPO(1, 1, 1, 1, 1, 1, 1, 1, 1, 0), .expect_error = "Invalid CPU topology: CPU topology parameters must " "be greater than zero", }, @@ -977,6 +1002,7 @@ static void machine_full_topo_class_init(ObjectClass *oc, void *data) mc->smp_props.books_supported = true; mc->smp_props.dies_supported = true; mc->smp_props.clusters_supported = true; + mc->smp_props.modules_supported = true; } static void test_generic_valid(const void *opaque) @@ -1396,30 +1422,41 @@ static void test_full_topo(const void *opaque) MachineState *ms = MACHINE(obj); MachineClass *mc = MACHINE_GET_CLASS(obj); SMPTestData data = {}; - unsigned int drawers = 5, books = 3, dies = 2, clusters = 7, multiplier; + unsigned int drawers, books, dies, clusters, modules, multiplier; int i; - multiplier = drawers * books * dies * clusters; + drawers = 5; + books = 3; + dies = 2; + clusters = 3; + modules = 2; + + multiplier = drawers * books * dies * clusters * modules; for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { data = data_generic_valid[i]; unsupported_params_init(mc, &data); /* - * when drawers, books, dies and clusters parameters are omitted, - * they will be set as 1. + * when drawers, books, dies, clusters and modules parameters are + * omitted, they will be set as 1. */ data.expect_prefer_sockets.drawers = 1; data.expect_prefer_sockets.books = 1; data.expect_prefer_sockets.dies = 1; data.expect_prefer_sockets.clusters = 1; + data.expect_prefer_sockets.modules = 1; data.expect_prefer_cores.drawers = 1; data.expect_prefer_cores.books = 1; data.expect_prefer_cores.dies = 1; data.expect_prefer_cores.clusters = 1; + data.expect_prefer_cores.modules = 1; smp_parse_test(ms, &data, true); - /* when drawers, books, dies and clusters parameters are specified. */ + /* + * when drawers, books, dies, clusters and modules parameters + * are specified. + */ data.config.has_drawers = true; data.config.drawers = drawers; data.config.has_books = true; @@ -1428,6 +1465,8 @@ static void test_full_topo(const void *opaque) data.config.dies = dies; data.config.has_clusters = true; data.config.clusters = clusters; + data.config.has_modules = true; + data.config.modules = modules; if (data.config.has_cpus) { data.config.cpus *= multiplier; @@ -1440,6 +1479,7 @@ static void test_full_topo(const void *opaque) data.expect_prefer_sockets.books = books; data.expect_prefer_sockets.dies = dies; data.expect_prefer_sockets.clusters = clusters; + data.expect_prefer_sockets.modules = modules; data.expect_prefer_sockets.cpus *= multiplier; data.expect_prefer_sockets.max_cpus *= multiplier; @@ -1447,6 +1487,7 @@ static void test_full_topo(const void *opaque) data.expect_prefer_cores.books = books; data.expect_prefer_cores.dies = dies; data.expect_prefer_cores.clusters = clusters; + data.expect_prefer_cores.modules = modules; data.expect_prefer_cores.cpus *= multiplier; data.expect_prefer_cores.max_cpus *= multiplier; -- cgit 1.4.1