[LTP] [PATCH v2 07/31] testcases: sysfs: Add sys_cpu_topology02

Cyril Hrubis <[email protected]>
Newsgroups it.linux.lists.ltp
Message-ID <[email protected]>
A test for /sys/devices/system/cpu/cpu*/topology/* files.

Signed-off-by: Cyril Hrubis <[email protected]>
---
 runtest/sysfs                                 |   1 +
 .../sysfs/devices/system/cpu/.gitignore       |   1 +
 .../devices/system/cpu/sys_cpu_topology02.c   | 112 ++++++++++++++++++
 3 files changed, 114 insertions(+)
 create mode 100644 testcases/kernel/sysfs/devices/system/cpu/sys_cpu_topology02.c

diff --git a/runtest/sysfs b/runtest/sysfs
index 4fc8f1eb2..b1daab68f 100644
--- a/runtest/sysfs
+++ b/runtest/sysfs
@@ -3,3 +3,4 @@ sys_kernel01 sys_kernel01
 sys_clocksource01 sys_clocksource01
 sys_node01 sys_node01
 sys_cpu_topology01 sys_cpu_topology01
+sys_cpu_topology02 sys_cpu_topology02
diff --git a/testcases/kernel/sysfs/devices/system/cpu/.gitignore b/testcases/kernel/sysfs/devices/system/cpu/.gitignore
index 0615aff77..a688a9b50 100644
--- a/testcases/kernel/sysfs/devices/system/cpu/.gitignore
+++ b/testcases/kernel/sysfs/devices/system/cpu/.gitignore
@@ -1 +1,2 @@
 /sys_cpu_topology01
+/sys_cpu_topology02
diff --git a/testcases/kernel/sysfs/devices/system/cpu/sys_cpu_topology02.c b/testcases/kernel/sysfs/devices/system/cpu/sys_cpu_topology02.c
new file mode 100644
index 000000000..536b23c3a
--- /dev/null
+++ b/testcases/kernel/sysfs/devices/system/cpu/sys_cpu_topology02.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <[email protected]>
+ */
+
+/*\
+ * Sanity checks for the per-CPU topology attributes exported under
+ * /sys/devices/system/cpu/cpuN/topology/.
+ *
+ * The topology masks describe how a CPU relates to the others. They are nested
+ * from the smallest (SMT threads) to the largest (package) group, so for every
+ * online CPU the test verifies that:
+ *
+ * - thread_siblings_list is a subset of core_cpus_list
+ * - core_cpus_list is a subset of package_cpus_list
+ * - package_cpus_list is a subset of the present CPUs, not just the online
+ *   ones: the whole topology/ directory (package_cpus_list included) is
+ *   added/removed per-CPU on hotplug (drivers/base/topology.c registers it
+ *   against a cpuhp state), so it only ever lists CPUs that share the
+ *   package and are also online right now. Comparing against "present"
+ *   instead of "online" avoids relying on that always being reliably kept
+ *   in sync on every architecture, and avoids a spurious failure if a
+ *   sibling CPU is hot-unplugged concurrently with this test running.
+ * - the CPU itself is contained in its own thread_siblings_list
+ * - core_id is in [0, highest possible CPU id], since there can be at most
+ *   as many cores as possible CPUs (every core has at least one thread)
+ * - physical_package_id is in [-1, highest possible CPU id]. -1 is a
+ *   legitimate value here, not just a range extension for safety: per
+ *   include/linux/topology.h, -1 is the architecture-neutral default for
+ *   topology_physical_package_id() (and die_id/cluster_id/book_id/
+ *   drawer_id) on any architecture, or any CPU type within one, that does
+ *   not implement package detection. topology_core_id() does not have this
+ *   documented -1 fallback (its generic default is 0), so core_id is not
+ *   given the same allowance.
+ *
+ * All checks skip gracefully with TCONF when a particular attribute is not
+ * present, as the exact set of topology files differs between kernel versions
+ * and architectures.
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include <unistd.h>
+#include "tst_test.h"
+#include "tst_sysfs_assert.h"
+
+#define SYS_CPU "/sys/devices/system/cpu"
+
+static void check_self_in_threads(int cpu)
+{
+	TST_SYSFS_ASSERT_LIST_CONTAINS(cpu,
+		SYS_CPU "/cpu%d/topology/thread_siblings_list", cpu);
+}
+
+static void check_cpu_topology(int cpu, int poss_max_id)
+{
+	char sub[PATH_MAX], super[PATH_MAX];
+
+	if (access(SYS_CPU, F_OK))
+		return;
+
+	if (!tst_sysfs_exists(SYS_CPU "/cpu%d/topology/core_id", cpu)) {
+		tst_res(TCONF, "cpu%d has no topology directory", cpu);
+		return;
+	}
+
+	tst_res(TINFO, "Checking cpu%d topology", cpu);
+
+	TST_SYSFS_ASSERT_RANGELL(0, poss_max_id,
+			       SYS_CPU "/cpu%d/topology/core_id", cpu);
+
+	TST_SYSFS_ASSERT_RANGELL(-1, poss_max_id,
+			       SYS_CPU "/cpu%d/topology/physical_package_id",
+			       cpu);
+
+	snprintf(sub, sizeof(sub),
+		 SYS_CPU "/cpu%d/topology/thread_siblings_list", cpu);
+	snprintf(super, sizeof(super),
+		 SYS_CPU "/cpu%d/topology/core_cpus_list", cpu);
+	TST_SYSFS_ASSERT_LIST_SUBSET(sub, super);
+
+	snprintf(sub, sizeof(sub),
+		 SYS_CPU "/cpu%d/topology/core_cpus_list", cpu);
+	snprintf(super, sizeof(super),
+		 SYS_CPU "/cpu%d/topology/package_cpus_list", cpu);
+	TST_SYSFS_ASSERT_LIST_SUBSET(sub, super);
+
+	snprintf(sub, sizeof(sub),
+		 SYS_CPU "/cpu%d/topology/package_cpus_list", cpu);
+	TST_SYSFS_ASSERT_LIST_SUBSET(sub, SYS_CPU "/present");
+
+	check_self_in_threads(cpu);
+}
+
+static void do_test(void)
+{
+	int count, max_id, poss_count, poss_max_id, cpu;
+
+	if (TST_SYSFS_ASSERT_PARSE_LIST(&count, &max_id, SYS_CPU "/online"))
+		return;
+
+	if (TST_SYSFS_ASSERT_PARSE_LIST(&poss_count, &poss_max_id,
+					SYS_CPU "/possible"))
+		return;
+
+	for (cpu = 0; cpu <= max_id; cpu++)
+		check_cpu_topology(cpu, poss_max_id);
+}
+
+static struct tst_test test = {
+	.test_all = do_test,
+};
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.