All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yanan Wang via <qemu-devel@nongnu.org>
To: <qemu-devel@nongnu.org>, <qemu-arm@nongnu.org>
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
	"Andrew Jones" <drjones@redhat.com>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	"Igor Mammedov" <imammedo@redhat.com>,
	"Shannon Zhao" <shannon.zhaosl@gmail.com>,
	"Ani Sinha" <ani@anisinha.ca>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Eric Blake" <eblake@redhat.com>,
	wanghaibin.wang@huawei.com, "Yanan Wang" <wangyanan55@huawei.com>
Subject: [PATCH v5 04/14] tests/unit/test-smp-parse: Add testcases for CPU clusters
Date: Tue, 28 Dec 2021 17:22:11 +0800	[thread overview]
Message-ID: <20211228092221.21068-5-wangyanan55@huawei.com> (raw)
In-Reply-To: <20211228092221.21068-1-wangyanan55@huawei.com>

Add testcases for parsing of the four-level CPU topology hierarchy,
ie sockets/clusters/cores/threads, which will be supported on ARM
virt machines.

Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
---
 tests/unit/test-smp-parse.c | 130 ++++++++++++++++++++++++++++++++++--
 1 file changed, 123 insertions(+), 7 deletions(-)

diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c
index b6df8137fc..331719bbc4 100644
--- a/tests/unit/test-smp-parse.c
+++ b/tests/unit/test-smp-parse.c
@@ -61,6 +61,20 @@
             .has_maxcpus = hf, .maxcpus = f,                  \
         }
 
+/*
+ * Currently a 4-level topology hierarchy is supported on ARM virt machines
+ *  -sockets/clusters/cores/threads
+ */
+#define SMP_CONFIG_WITH_CLUSTERS(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \
+        {                                                     \
+            .has_cpus     = ha, .cpus     = a,                \
+            .has_sockets  = hb, .sockets  = b,                \
+            .has_clusters = hc, .clusters = c,                \
+            .has_cores    = hd, .cores    = d,                \
+            .has_threads  = he, .threads  = e,                \
+            .has_maxcpus  = hf, .maxcpus  = f,                \
+        }
+
 /**
  * @config - the given SMP configuration
  * @expect_prefer_sockets - the expected parsing result for the
@@ -290,6 +304,10 @@ static const struct SMPTestData data_generic_invalid[] = {
         /* config: -smp 2,dies=2 */
         .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
         .expect_error = "dies not supported by this machine's CPU topology",
+    }, {
+        /* config: -smp 2,clusters=2 */
+        .config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0),
+        .expect_error = "clusters not supported by this machine's CPU topology",
     }, {
         /* config: -smp 8,sockets=2,cores=4,threads=2,maxcpus=8 */
         .config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8),
@@ -337,20 +355,40 @@ static const struct SMPTestData data_with_dies_invalid[] = {
     },
 };
 
+static const struct SMPTestData data_with_clusters_invalid[] = {
+    {
+        /* config: -smp 16,sockets=2,clusters=2,cores=4,threads=2,maxcpus=16 */
+        .config = SMP_CONFIG_WITH_CLUSTERS(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16),
+        .expect_error = "Invalid CPU topology: "
+                        "product of the hierarchy must match maxcpus: "
+                        "sockets (2) * clusters (2) * cores (4) * threads (2) "
+                        "!= maxcpus (16)",
+    }, {
+        /* config: -smp 34,sockets=2,clusters=2,cores=4,threads=2,maxcpus=32 */
+        .config = SMP_CONFIG_WITH_CLUSTERS(T, 34, T, 2, T, 2, T, 4, T, 2, T, 32),
+        .expect_error = "Invalid CPU topology: "
+                        "maxcpus must be equal to or greater than smp: "
+                        "sockets (2) * clusters (2) * cores (4) * threads (2) "
+                        "== maxcpus (32) < smp_cpus (34)",
+    },
+};
+
 static char *smp_config_to_string(const SMPConfiguration *config)
 {
     return g_strdup_printf(
         "(SMPConfiguration) {\n"
-        "    .has_cpus    = %5s, cpus    = %" PRId64 ",\n"
-        "    .has_sockets = %5s, sockets = %" PRId64 ",\n"
-        "    .has_dies    = %5s, dies    = %" PRId64 ",\n"
-        "    .has_cores   = %5s, cores   = %" PRId64 ",\n"
-        "    .has_threads = %5s, threads = %" PRId64 ",\n"
-        "    .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n"
+        "    .has_cpus     = %5s, cpus     = %" PRId64 ",\n"
+        "    .has_sockets  = %5s, sockets  = %" PRId64 ",\n"
+        "    .has_dies     = %5s, dies     = %" PRId64 ",\n"
+        "    .has_clusters = %5s, clusters = %" PRId64 ",\n"
+        "    .has_cores    = %5s, cores    = %" PRId64 ",\n"
+        "    .has_threads  = %5s, threads  = %" PRId64 ",\n"
+        "    .has_maxcpus  = %5s, maxcpus  = %" PRId64 ",\n"
         "}",
         config->has_cpus ? "true" : "false", config->cpus,
         config->has_sockets ? "true" : "false", config->sockets,
         config->has_dies ? "true" : "false", config->dies,
+        config->has_clusters ? "true" : "false", config->clusters,
         config->has_cores ? "true" : "false", config->cores,
         config->has_threads ? "true" : "false", config->threads,
         config->has_maxcpus ? "true" : "false", config->maxcpus);
@@ -363,11 +401,12 @@ static char *cpu_topology_to_string(const CpuTopology *topo)
         "    .cpus     = %u,\n"
         "    .sockets  = %u,\n"
         "    .dies     = %u,\n"
+        "    .clusters = %u,\n"
         "    .cores    = %u,\n"
         "    .threads  = %u,\n"
         "    .max_cpus = %u,\n"
         "}",
-        topo->cpus, topo->sockets, topo->dies,
+        topo->cpus, topo->sockets, topo->dies, topo->clusters,
         topo->cores, topo->threads, topo->max_cpus);
 }
 
@@ -391,6 +430,7 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config,
             (ms->smp.cpus == expect_topo->cpus) &&
             (ms->smp.sockets == expect_topo->sockets) &&
             (ms->smp.dies == expect_topo->dies) &&
+            (ms->smp.clusters == expect_topo->clusters) &&
             (ms->smp.cores == expect_topo->cores) &&
             (ms->smp.threads == expect_topo->threads) &&
             (ms->smp.max_cpus == expect_topo->max_cpus)) {
@@ -472,6 +512,11 @@ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data)
         data->expect_prefer_sockets.dies = 1;
         data->expect_prefer_cores.dies = 1;
     }
+
+    if (!mc->smp_props.clusters_supported) {
+        data->expect_prefer_sockets.clusters = 1;
+        data->expect_prefer_cores.clusters = 1;
+    }
 }
 
 static void machine_base_class_init(ObjectClass *oc, void *data)
@@ -491,6 +536,7 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data)
     mc->max_cpus = MAX_CPUS;
 
     mc->smp_props.dies_supported = false;
+    mc->smp_props.clusters_supported = false;
 }
 
 static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
@@ -502,6 +548,7 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data)
     mc->max_cpus = 511;
 
     mc->smp_props.dies_supported = false;
+    mc->smp_props.clusters_supported = false;
 }
 
 static void machine_with_dies_class_init(ObjectClass *oc, void *data)
@@ -512,6 +559,18 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data)
     mc->max_cpus = MAX_CPUS;
 
     mc->smp_props.dies_supported = true;
+    mc->smp_props.clusters_supported = false;
+}
+
+static void machine_with_clusters_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->min_cpus = MIN_CPUS;
+    mc->max_cpus = MAX_CPUS;
+
+    mc->smp_props.clusters_supported = true;
+    mc->smp_props.dies_supported = false;
 }
 
 static void test_generic_valid(const void *opaque)
@@ -607,6 +666,56 @@ static void test_with_dies(const void *opaque)
     object_unref(obj);
 }
 
+static void test_with_clusters(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_clusters = 2;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) {
+        data = data_generic_valid[i];
+        unsupported_params_init(mc, &data);
+
+        /* when clusters parameter is omitted, it will be set as 1 */
+        data.expect_prefer_sockets.clusters = 1;
+        data.expect_prefer_cores.clusters = 1;
+
+        smp_parse_test(ms, &data, true);
+
+        /* when clusters parameter is specified */
+        data.config.has_clusters = true;
+        data.config.clusters = num_clusters;
+        if (data.config.has_cpus) {
+            data.config.cpus *= num_clusters;
+        }
+        if (data.config.has_maxcpus) {
+            data.config.maxcpus *= num_clusters;
+        }
+
+        data.expect_prefer_sockets.clusters = num_clusters;
+        data.expect_prefer_sockets.cpus *= num_clusters;
+        data.expect_prefer_sockets.max_cpus *= num_clusters;
+        data.expect_prefer_cores.clusters = num_clusters;
+        data.expect_prefer_cores.cpus *= num_clusters;
+        data.expect_prefer_cores.max_cpus *= num_clusters;
+
+        smp_parse_test(ms, &data, true);
+    }
+
+    for (i = 0; i < ARRAY_SIZE(data_with_clusters_invalid); i++) {
+        data = data_with_clusters_invalid[i];
+        unsupported_params_init(mc, &data);
+
+        smp_parse_test(ms, &data, false);
+    }
+
+    object_unref(obj);
+}
+
 /* Type info of the tested machine */
 static const TypeInfo smp_machine_types[] = {
     {
@@ -628,6 +737,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-clusters"),
+        .parent         = TYPE_MACHINE,
+        .class_init     = machine_with_clusters_class_init,
     }
 };
 
@@ -648,6 +761,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_clusters",
+                         MACHINE_TYPE_NAME("smp-with-clusters"),
+                         test_with_clusters);
 
     g_test_run();
 
-- 
2.27.0



  parent reply	other threads:[~2021-12-28  9:24 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-28  9:22 [PATCH v5 00/14] ARM virt: Introduce CPU clusters topology support Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 01/14] qemu-options: Improve readability of SMP related Docs Yanan Wang via
2021-12-28 19:11   ` Philippe Mathieu-Daudé
2021-12-28  9:22 ` [PATCH v5 02/14] hw/core/machine: Introduce CPU cluster topology support Yanan Wang via
2021-12-28 19:17   ` Philippe Mathieu-Daudé
2021-12-29  3:48     ` wangyanan (Y) via
2021-12-29 10:44       ` Philippe Mathieu-Daudé
2021-12-29 13:04         ` wangyanan (Y) via
2021-12-29 15:44           ` Philippe Mathieu-Daudé
2022-01-14 11:34     ` Markus Armbruster
2021-12-28  9:22 ` [PATCH v5 03/14] hw/core/machine: Wrap target specific parameters together Yanan Wang via
2021-12-28 19:23   ` Philippe Mathieu-Daudé
2021-12-29  1:40     ` wangyanan (Y) via
2021-12-28  9:22 ` Yanan Wang via [this message]
2021-12-28 19:26   ` [PATCH v5 04/14] tests/unit/test-smp-parse: Add testcases for CPU clusters Philippe Mathieu-Daudé
2021-12-28  9:22 ` [PATCH v5 05/14] tests/unit/test-smp-parse: No need to explicitly zero MachineClass members Yanan Wang via
2021-12-28 15:58   ` Philippe Mathieu-Daudé
2021-12-28  9:22 ` [PATCH v5 06/14] tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in machine_base_class_init Yanan Wang via
2021-12-28 19:28   ` Philippe Mathieu-Daudé
2021-12-28  9:22 ` [PATCH v5 07/14] MAINTAINERS: Self-recommended as reviewer of "Machine core" Yanan Wang via
2021-12-28 15:58   ` Philippe Mathieu-Daudé
2021-12-28  9:22 ` [PATCH v5 08/14] hw/arm/virt: Support clusters on ARM virt machines Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 09/14] hw/arm/virt: Support cluster level in DT cpu-map Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 10/14] hw/acpi/aml-build: Improve scalability of PPTT generation Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 11/14] hw/arm/virt-acpi-build: Make an ARM specific PPTT generator Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 12/14] tests/acpi/bios-tables-test: Allow changes to virt/PPTT file Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 13/14] hw/arm/virt-acpi-build: Support cluster level in PPTT generation Yanan Wang via
2021-12-28  9:22 ` [PATCH v5 14/14] tests/acpi/bios-table-test: Update expected virt/PPTT file Yanan Wang via
2021-12-31 12:05 ` [PATCH v5 00/14] ARM virt: Introduce CPU clusters topology support Philippe Mathieu-Daudé
2022-01-03  9:08 ` wangyanan (Y) via

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211228092221.21068-5-wangyanan55@huawei.com \
    --to=qemu-devel@nongnu.org \
    --cc=ani@anisinha.ca \
    --cc=armbru@redhat.com \
    --cc=drjones@redhat.com \
    --cc=eblake@redhat.com \
    --cc=eduardo@habkost.net \
    --cc=imammedo@redhat.com \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=shannon.zhaosl@gmail.com \
    --cc=wanghaibin.wang@huawei.com \
    --cc=wangyanan55@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.