From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
To: "Claudio Imbrenda" <imbrenda@linux.ibm.com>,
"Nico Böhr" <nrb@linux.ibm.com>,
"Janosch Frank" <frankja@linux.ibm.com>
Cc: Nina Schoetterl-Glausch <nsg@linux.ibm.com>,
Andrew Jones <andrew.jones@linux.dev>,
Ricardo Koller <ricarkol@google.com>,
Thomas Huth <thuth@redhat.com>,
Nikos Nikoleris <nikos.nikoleris@arm.com>,
Colton Lewis <coltonlewis@google.com>,
Sean Christopherson <seanjc@google.com>,
Shaoqin Huang <shahuang@redhat.com>,
kvm@vger.kernel.org, linux-s390@vger.kernel.org,
David Hildenbrand <david@redhat.com>
Subject: [kvm-unit-tests PATCH 08/10] s390x: topology: Rewrite topology list test
Date: Fri, 20 Oct 2023 16:48:58 +0200 [thread overview]
Message-ID: <20231020144900.2213398-9-nsg@linux.ibm.com> (raw)
In-Reply-To: <20231020144900.2213398-1-nsg@linux.ibm.com>
Rewrite recursion with separate functions for checking containers,
containers containing CPUs and CPUs.
This improves comprehension and allows for more tests.
We now also test for ordering of CPU TLEs and number of child entries.
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
---
lib/s390x/stsi.h | 36 +++++----
s390x/topology.c | 201 ++++++++++++++++++++++++++++-------------------
2 files changed, 142 insertions(+), 95 deletions(-)
diff --git a/lib/s390x/stsi.h b/lib/s390x/stsi.h
index 1e9d0958..f2290ca7 100644
--- a/lib/s390x/stsi.h
+++ b/lib/s390x/stsi.h
@@ -30,15 +30,18 @@ struct sysinfo_3_2_2 {
};
#define CPUS_TLE_RES_BITS 0x00fffffff8000000UL
-struct topology_cpu {
- uint8_t nl;
- uint8_t reserved1[3];
- uint8_t reserved4:5;
- uint8_t d:1;
- uint8_t pp:2;
- uint8_t type;
- uint16_t origin;
- uint64_t mask;
+union topology_cpu {
+ uint64_t raw[2];
+ struct {
+ uint8_t nl;
+ uint8_t reserved1[3];
+ uint8_t reserved4:5;
+ uint8_t d:1;
+ uint8_t pp:2;
+ uint8_t type;
+ uint16_t origin;
+ uint64_t mask;
+ };
};
enum topology_polarization {
@@ -53,16 +56,19 @@ enum cpu_type {
};
#define CONTAINER_TLE_RES_BITS 0x00ffffffffffff00UL
-struct topology_container {
- uint8_t nl;
- uint8_t reserved[6];
- uint8_t id;
+union topology_container {
+ uint64_t raw;
+ struct {
+ uint8_t nl;
+ uint8_t reserved[6];
+ uint8_t id;
+ };
};
union topology_entry {
uint8_t nl;
- struct topology_cpu cpu;
- struct topology_container container;
+ union topology_cpu cpu;
+ union topology_container container;
};
#define CPU_TOPOLOGY_MAX_LEVEL 6
diff --git a/s390x/topology.c b/s390x/topology.c
index df158aef..037d22cd 100644
--- a/s390x/topology.c
+++ b/s390x/topology.c
@@ -2,7 +2,7 @@
/*
* CPU Topology
*
- * Copyright IBM Corp. 2022
+ * Copyright IBM Corp. 2022, 2023
*
* Authors:
* Pierre Morel <pmorel@linux.ibm.com>
@@ -23,7 +23,6 @@ static uint8_t pagebuf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
static int max_nested_lvl;
static int number_of_cpus;
-static int cpus_in_masks;
static int max_cpus;
/*
@@ -237,82 +236,6 @@ done:
report_prefix_pop();
}
-/**
- * check_tle:
- * @tc: pointer to first TLE
- *
- * Recursively check the containers TLEs until we
- * find a CPU TLE.
- */
-static uint8_t *check_tle(void *tc)
-{
- struct topology_container *container = tc;
- struct topology_cpu *cpus;
- int n;
-
- if (container->nl) {
- report_info("NL: %d id: %d", container->nl, container->id);
-
- report(!(*(uint64_t *)tc & CONTAINER_TLE_RES_BITS),
- "reserved bits %016lx",
- *(uint64_t *)tc & CONTAINER_TLE_RES_BITS);
-
- return check_tle(tc + sizeof(*container));
- }
-
- report_info("NL: %d", container->nl);
- cpus = tc;
-
- report(!(*(uint64_t *)tc & CPUS_TLE_RES_BITS), "reserved bits %016lx",
- *(uint64_t *)tc & CPUS_TLE_RES_BITS);
-
- report(cpus->type == CPU_TYPE_IFL, "type IFL");
-
- report_info("origin: %d", cpus->origin);
- report_info("mask: %016lx", cpus->mask);
- report_info("dedicated: %d entitlement: %d", cpus->d, cpus->pp);
-
- n = __builtin_popcountl(cpus->mask);
- report(n <= expected_topo_lvl[0], "CPUs per mask: %d out of max %d",
- n, expected_topo_lvl[0]);
- cpus_in_masks += n;
-
- if (!cpus->d)
- report_skip("Not dedicated");
- else
- report(cpus->pp == POLARIZATION_VERTICAL_HIGH ||
- cpus->pp == POLARIZATION_HORIZONTAL,
- "Dedicated CPUs are either horizontally polarized or have high entitlement");
-
- return tc + sizeof(*cpus);
-}
-
-/**
- * stsi_check_tle_coherency:
- * @info: Pointer to the stsi information
- *
- * We verify that we get the expected number of Topology List Entry
- * containers for a specific level.
- */
-static void stsi_check_tle_coherency(struct sysinfo_15_1_x *info)
-{
- void *tc, *end;
-
- report_prefix_push("TLE");
- cpus_in_masks = 0;
-
- tc = info->tle;
- end = (void *)info + info->length;
-
- while (tc < end)
- tc = check_tle(tc);
-
- report(cpus_in_masks == number_of_cpus, "CPUs in mask %d",
- cpus_in_masks);
-
- report_prefix_pop();
-}
-
/**
* stsi_get_sysib:
* @info: pointer to the STSI info structure
@@ -342,6 +265,124 @@ static int stsi_get_sysib(struct sysinfo_15_1_x *info, int sel2)
return ret;
}
+static int check_cpu(union topology_cpu *cpu,
+ union topology_container *parent)
+{
+ report_prefix_pushf("%d:%d:%d:%d", cpu->d, cpu->pp, cpu->type, cpu->origin);
+
+ report(!(cpu->raw[0] & CPUS_TLE_RES_BITS), "reserved bits %016lx",
+ cpu->raw[0] & CPUS_TLE_RES_BITS);
+
+ report(cpu->type == CPU_TYPE_IFL, "type IFL");
+
+ if (cpu->d)
+ report(cpu->pp == POLARIZATION_VERTICAL_HIGH ||
+ cpu->pp == POLARIZATION_HORIZONTAL,
+ "Dedicated CPUs are either horizontally polarized or have high entitlement");
+ else
+ report_skip("Not dedicated");
+
+ report_prefix_pop();
+
+ return __builtin_popcountl(cpu->mask);
+}
+
+static union topology_container *check_child_cpus(struct sysinfo_15_1_x *info,
+ union topology_container *cont,
+ union topology_cpu *child,
+ unsigned int *cpus_in_masks)
+{
+ void *last = ((void *)info) + info->length;
+ union topology_cpu *prev_cpu = NULL;
+ unsigned int cpus = 0;
+ int i;
+
+ for (i = 0; (void *)&child[i] < last && child[i].nl == 0; i++) {
+ cpus += check_cpu(&child[i], cont);
+ if (prev_cpu) {
+ report(prev_cpu->type <= child[i].type, "Correct ordering wrt type");
+ if (prev_cpu->type < child[i].type)
+ continue;
+ report(prev_cpu->pp >= child[i].pp, "Correct ordering wrt polarization");
+ if (prev_cpu->pp > child[i].pp)
+ continue;
+ report(prev_cpu->d || !child[i].d, "Correct ordering wrt dedication");
+ if (prev_cpu->d && !child[i].d)
+ continue;
+ report(prev_cpu->origin <= child[i].origin, "Correct ordering wrt origin");
+ }
+ prev_cpu = &child[i];
+ }
+ report(cpus <= expected_topo_lvl[0], "%d children <= max of %d",
+ cpus, expected_topo_lvl[0]);
+ *cpus_in_masks += cpus;
+
+ return (union topology_container *)&child[i];
+}
+
+static union topology_container *check_container(struct sysinfo_15_1_x *info,
+ union topology_container *cont,
+ union topology_entry *child,
+ unsigned int *cpus_in_masks);
+
+static union topology_container *check_child_containers(struct sysinfo_15_1_x *info,
+ union topology_container *cont,
+ union topology_container *child,
+ unsigned int *cpus_in_masks)
+{
+ void *last = ((void *)info) + info->length;
+ union topology_container *entry;
+ int i;
+
+ for (i = 0, entry = child; (void *)entry < last && entry->nl == cont->nl - 1; i++) {
+ entry = check_container(info, entry, (union topology_entry *)(entry + 1),
+ cpus_in_masks);
+ }
+ if (max_nested_lvl == info->mnest)
+ report(i <= expected_topo_lvl[cont->nl - 1], "%d children <= max of %d",
+ i, expected_topo_lvl[cont->nl - 1]);
+
+ return entry;
+}
+
+static union topology_container *check_container(struct sysinfo_15_1_x *info,
+ union topology_container *cont,
+ union topology_entry *child,
+ unsigned int *cpus_in_masks)
+{
+ union topology_container *entry;
+
+ report_prefix_pushf("%d", cont->id);
+
+ report(cont->nl - 1 == child->nl, "Level %d one above child level %d",
+ cont->nl, child->nl);
+ report(!(cont->raw & CONTAINER_TLE_RES_BITS), "reserved bits %016lx",
+ cont->raw & CONTAINER_TLE_RES_BITS);
+
+ if (cont->nl > 1)
+ entry = check_child_containers(info, cont, &child->container, cpus_in_masks);
+ else
+ entry = check_child_cpus(info, cont, &child->cpu, cpus_in_masks);
+
+ report_prefix_pop();
+ return entry;
+}
+
+static void check_topology_list(struct sysinfo_15_1_x *info, int sel2)
+{
+ union topology_container dummy = { .nl = sel2, .id = 0 };
+ unsigned int cpus_in_masks = 0;
+
+ report_prefix_push("TLE");
+
+ check_container(info, &dummy, info->tle, &cpus_in_masks);
+ report(cpus_in_masks == number_of_cpus,
+ "Number of CPUs %d equals %d CPUs in masks",
+ number_of_cpus, cpus_in_masks);
+
+ report_prefix_pop();
+}
+
/**
* check_sysinfo_15_1_x:
* @info: pointer to the STSI info structure
@@ -372,7 +413,7 @@ static void check_sysinfo_15_1_x(struct sysinfo_15_1_x *info, int sel2)
}
stsi_check_header(info, sel2);
- stsi_check_tle_coherency(info);
+ check_topology_list(info, sel2);
vertical:
report_prefix_pop();
@@ -385,7 +426,7 @@ vertical:
}
stsi_check_header(info, sel2);
- stsi_check_tle_coherency(info);
+ check_topology_list(info, sel2);
report_prefix_pop();
end:
--
2.41.0
next prev parent reply other threads:[~2023-10-20 15:03 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-20 14:48 [kvm-unit-tests PATCH 00/10] s390x: topology: Fixes and extension Nina Schoetterl-Glausch
2023-10-20 14:48 ` [kvm-unit-tests PATCH 01/10] s390x: topology: Introduce enums for polarization & cpu type Nina Schoetterl-Glausch
2023-10-25 11:56 ` Nico Boehr
2023-10-25 11:58 ` Janosch Frank
2023-10-20 14:48 ` [kvm-unit-tests PATCH 02/10] s390x: topology: Fix report message Nina Schoetterl-Glausch
2023-10-25 11:59 ` Janosch Frank
2023-10-20 14:48 ` [kvm-unit-tests PATCH 03/10] s390x: topology: Use function parameter in stsi_get_sysib Nina Schoetterl-Glausch
2023-10-20 14:48 ` [kvm-unit-tests PATCH 04/10] s390x: topology: Fix parsing loop Nina Schoetterl-Glausch
2023-10-25 12:00 ` Janosch Frank
2023-10-20 14:48 ` [kvm-unit-tests PATCH 05/10] s390x: topology: Make some report messages unique Nina Schoetterl-Glausch
2023-10-20 14:48 ` [kvm-unit-tests PATCH 06/10] s390x: topology: Refine stsi header test Nina Schoetterl-Glausch
2023-10-25 14:11 ` Janosch Frank
2023-10-20 14:48 ` [kvm-unit-tests PATCH 07/10] s390x: topology: Rename topology_core to topology_cpu Nina Schoetterl-Glausch
2023-10-20 14:48 ` Nina Schoetterl-Glausch [this message]
2023-10-20 14:48 ` [kvm-unit-tests PATCH 09/10] scripts: Implement multiline strings for extra_params Nina Schoetterl-Glausch
2023-10-25 17:50 ` Thomas Huth
2023-10-25 17:58 ` Nina Schoetterl-Glausch
2023-10-20 14:49 ` [kvm-unit-tests PATCH 10/10] s390x: topology: Add complex topology test Nina Schoetterl-Glausch
2023-10-25 12:21 ` [kvm-unit-tests PATCH 00/10] s390x: topology: Fixes and extension Nico Boehr
[not found] ` <0f132157ec6437326c6bd63f8be18976b19f058a.camel@linux.ibm.com>
2023-10-30 7:30 ` Nico Boehr
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=20231020144900.2213398-9-nsg@linux.ibm.com \
--to=nsg@linux.ibm.com \
--cc=andrew.jones@linux.dev \
--cc=coltonlewis@google.com \
--cc=david@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=imbrenda@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=nikos.nikoleris@arm.com \
--cc=nrb@linux.ibm.com \
--cc=ricarkol@google.com \
--cc=seanjc@google.com \
--cc=shahuang@redhat.com \
--cc=thuth@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox