All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cyril Hrubis <chrubis@suse.cz>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v4 07/31] testcases: sysfs: Add sys_cpu_topology02
Date: Thu, 27 Aug 2026 13:21:33 +0200	[thread overview]
Message-ID: <20260827112157.1748734-8-chrubis@suse.cz> (raw)
In-Reply-To: <20260827112157.1748734-1-chrubis@suse.cz>

A test for /sys/devices/system/cpu/cpu*/topology/* files.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 runtest/sysfs                                 |   1 +
 .../sysfs/devices/system/cpu/.gitignore       |   1 +
 .../devices/system/cpu/sys_cpu_topology02.c   | 132 ++++++++++++++++++
 3 files changed, 134 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..7098da9f3
--- /dev/null
+++ b/testcases/kernel/sysfs/devices/system/cpu/sys_cpu_topology02.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * 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] on physical
+ *   hardware, or just at least -1 under virtualization (see below). -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.
+ *
+ *   The upper bound on physical_package_id is dropped under virtualization:
+ *   store_cpu_topology() in drivers/base/arch_topology.c falls back to
+ *   physical_package_id = cpu_to_node(cpu) whenever ACPI/DT topology
+ *   parsing did not already populate it (common on minimal/generic arm64 VM
+ *   firmware without full ACPI PPTT tables). On physical hardware this
+ *   fallback is still bounded by the number of possible CPUs, since NUMA
+ *   node ids are compacted/renumbered from the firmware's proximity domains
+ *   and there can never be more NUMA nodes than CPUs (each node needs at
+ *   least one). But a VM's NUMA node numbering is a hypervisor/firmware
+ *   policy choice entirely unrelated to its own CPU count, e.g. mirroring a
+ *   large host's own (possibly sparse) NUMA node ids under NUMA
+ *   passthrough/vNUMA configuration, so the bound would not be meaningful
+ *   there and is dropped to avoid a false failure.
+ *
+ * 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"
+#include "tst_path_defs.h"
+
+static void check_self_in_threads(int cpu)
+{
+	TST_SYSFS_ASSERT_LIST_CONTAINS(cpu,
+		PATH_SYS_CPU "/cpu%d/topology/thread_siblings_list", cpu);
+}
+
+static void check_cpu_topology(int cpu, int poss_max_id, long pkg_max_id)
+{
+	char sub[PATH_MAX], super[PATH_MAX];
+
+	if (access(PATH_SYS_CPU, F_OK))
+		return;
+
+	if (!tst_sysfs_exists(PATH_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,
+			       PATH_SYS_CPU "/cpu%d/topology/core_id", cpu);
+
+	TST_SYSFS_ASSERT_RANGELL(-1, pkg_max_id,
+			       PATH_SYS_CPU "/cpu%d/topology/physical_package_id",
+			       cpu);
+
+	snprintf(sub, sizeof(sub),
+		 PATH_SYS_CPU "/cpu%d/topology/thread_siblings_list", cpu);
+	snprintf(super, sizeof(super),
+		 PATH_SYS_CPU "/cpu%d/topology/core_cpus_list", cpu);
+	TST_SYSFS_ASSERT_LIST_SUBSET(sub, super);
+
+	snprintf(sub, sizeof(sub),
+		 PATH_SYS_CPU "/cpu%d/topology/core_cpus_list", cpu);
+	snprintf(super, sizeof(super),
+		 PATH_SYS_CPU "/cpu%d/topology/package_cpus_list", cpu);
+	TST_SYSFS_ASSERT_LIST_SUBSET(sub, super);
+
+	snprintf(sub, sizeof(sub),
+		 PATH_SYS_CPU "/cpu%d/topology/package_cpus_list", cpu);
+	TST_SYSFS_ASSERT_LIST_SUBSET(sub, PATH_SYS_CPU "/present");
+
+	check_self_in_threads(cpu);
+}
+
+static void do_test(void)
+{
+	int count, max_id, poss_count, poss_max_id, cpu;
+	long pkg_max_id;
+
+	if (TST_SYSFS_ASSERT_PARSE_LIST(&count, &max_id, PATH_SYS_CPU "/online"))
+		return;
+
+	if (TST_SYSFS_ASSERT_PARSE_LIST(&poss_count, &poss_max_id,
+					PATH_SYS_CPU "/possible"))
+		return;
+
+	if (tst_is_virt(VIRT_ANY))
+		pkg_max_id = LONG_MAX;
+	else
+		pkg_max_id = poss_max_id;
+
+	for (cpu = 0; cpu <= max_id; cpu++)
+		check_cpu_topology(cpu, poss_max_id, pkg_max_id);
+}
+
+static struct tst_test test = {
+	.test_all = do_test,
+};
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  parent reply	other threads:[~2026-08-27 11:24 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27 11:21 [LTP] [PATCH v3 00/31] Add sysfs sanity tests Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 01/31] lib: Add tst_sysfs_assert Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 02/31] testcases: sysfs: Add sys_power01 Cyril Hrubis
2026-08-27 14:04   ` [LTP] lib: Add tst_sysfs_assert linuxtestproject.agent
2026-08-27 11:21 ` [LTP] [PATCH v4 03/31] testcases: sysfs: Add sys_kernel01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 04/31] testcases: sysfs: Add sys_clocksource01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 05/31] testcases: sysfs: Add sys_node01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 06/31] testcases: sysfs: Add sys_cpu_topology01 Cyril Hrubis
2026-08-27 11:21 ` Cyril Hrubis [this message]
2026-08-27 11:21 ` [LTP] [PATCH v4 08/31] testcases: sysfs: Add sys_cpu_vulnerabilities01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 09/31] testcases: sysfs: Add sys_cpu_smt01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 10/31] testcases: sysfs: Add sys_cpu_cache01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 11/31] testcases: sysfs: Add sys_clockevents01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 12/31] testcases: sysfs: Add sys_ata01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 13/31] testcases: sysfs: Add sys_bdi01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 14/31] testcases: sysfs: sys_hwmon01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 15/31] testcases: sysfs: sys_leds01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 16/31] testcases: sysfs: Add sys_wakeup01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 17/31] testcases: sysfs: Add sys_rtc01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 18/31] testcases: sysfs: Add sys_thermal01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 19/31] tst_netdevice: Add two more helper macros Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 20/31] testcases: sysfs: Add sys_net01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 21/31] testcases: sysfs: Add sys_net02 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 22/31] testcases: sysfs: Add sys_net03 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 23/31] testcases: sysfs: Add sys_net04 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 24/31] testcases: sysfs: Add sys_block_loop01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 25/31] testcases: sysfs: Add sys_block_queue01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 26/31] testcases: sysfs: Add sys_block_size01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 27/31] testcases: sysfs: Add sys_hugepages01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 28/31] testcases: sysfs: Add sys_hugepages02 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 29/31] testcases: sysfs: Add sys_ksm01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 30/31] testcases: sysfs: Add sys_mm_swap01 Cyril Hrubis
2026-08-27 11:21 ` [LTP] [PATCH v4 31/31] testcases: sysfs: Add sys_thp01 Cyril Hrubis
2026-08-28  8:32 ` [LTP] [PATCH v3 00/31] Add sysfs sanity tests Li Wang

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=20260827112157.1748734-8-chrubis@suse.cz \
    --to=chrubis@suse.cz \
    --cc=ltp@lists.linux.it \
    /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.