From 08ccb1ccbf520f4bd3e7095596fe70db7e7331e2 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Fri, 20 Oct 2023 13:48:19 +0200 Subject: [PATCH 1/2] tests/linux/gather: ignore gp_index/obj IDs Reading caches with opendir() from a sysdump dump can cause cache discovery to be reordered. Signed-off-by: Brice Goglin --- tests/hwloc/linux/gather/test-gather-topology.sh.in | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/hwloc/linux/gather/test-gather-topology.sh.in b/tests/hwloc/linux/gather/test-gather-topology.sh.in index 41f8dee57a..74c906d63e 100644 --- a/tests/hwloc/linux/gather/test-gather-topology.sh.in +++ b/tests/hwloc/linux/gather/test-gather-topology.sh.in @@ -62,7 +62,11 @@ export HWLOC_FSROOT=// echo "Saving current system topology to XML..." # ignore DAXDevice info attr because it won't appear in save2.xml unless we pass --io to gather below -if ! "$lstopo" --no-io -.xml | grep -v DAXDevice > "$tmpdir/save1.xml" ; then +if ! "$lstopo" --no-io -.xml \ + | sed -e 's/ id="obj[0-9]*"//' \ + | sed -e 's/ gp_index="[0-9]*"//' \ + | grep -v DAXDevice \ + > "$tmpdir/save1.xml" ; then error "Failed" exit 1 fi @@ -85,7 +89,10 @@ export HWLOC_FSROOT="$tmpdir/save" rm -f "$tmpdir/save/proc/hwloc-nofile-info" echo "Saving tarball topology to XML..." -if ! "$lstopo" --no-io "$tmpdir/save2.xml" ; then +if ! "$lstopo" --no-io -.xml \ + | sed -e 's/ id="obj[0-9]*"//' \ + | sed -e 's/ gp_index="[0-9]*"//' \ + > "$tmpdir/save2.xml" ; then error "Failed" exit 1 fi From ac86c4f676757cc6c6edb4f0dc6e0edf9f2ff390 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Fri, 20 Oct 2023 13:37:02 +0200 Subject: [PATCH 2/2] WIP linux/sysfs: use opendir() to list cpu caches Instead of trying to open all "index%u" from 0 to 9. Refs #434 Signed-off-by: Brice Goglin --- hwloc/topology-linux.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/hwloc/topology-linux.c b/hwloc/topology-linux.c index 050a7b01d7..6d7d8abc90 100644 --- a/hwloc/topology-linux.c +++ b/hwloc/topology-linux.c @@ -5032,11 +5032,18 @@ look_sysfscpu(struct hwloc_topology *topology, /* look at the caches */ if (topology->want_some_cpu_caches) { - for(j=0; j<10; j++) { + DIR *cachesdir; + struct dirent *dirent; + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/", i); + cachesdir = hwloc_opendir(str, data->root_fd); + if (cachesdir) { + while ((dirent = readdir(cachesdir)) != NULL) { char str2[20]; /* enough for a level number (one digit) or a type (Data/Instruction/Unified) */ hwloc_bitmap_t cacheset; - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/shared_cpu_map", i, j); + if (strncmp(dirent->d_name, "index", 5)) + continue; + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/shared_cpu_map", i, dirent->d_name); cacheset = hwloc__alloc_read_path_as_cpumask(str, data->root_fd); if (cacheset) { if (hwloc_bitmap_iszero(cacheset)) { @@ -5066,14 +5073,14 @@ look_sysfscpu(struct hwloc_topology *topology, struct hwloc_obj *cache; /* get the cache level depth */ - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/level", i, j); /* contains %u at least up to 4.19 */ + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/level", i, dirent->d_name); /* contains %u at least up to 4.19 */ if (hwloc_read_path_as_uint(str, &depth, data->root_fd) < 0) { hwloc_bitmap_free(cacheset); continue; } /* cache type */ - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/type", i, j); + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/type", i, dirent->d_name); if (hwloc_read_path_by_length(str, str2, sizeof(str2), data->root_fd) > 0) { if (!strncmp(str2, "Data", 4)) ctype = HWLOC_OBJ_CACHE_DATA; @@ -5084,7 +5091,7 @@ look_sysfscpu(struct hwloc_topology *topology, } /* cache id */ - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/id", i, j); + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/id", i, dirent->d_name); hwloc_read_path_as_uint(str, &id, data->root_fd); otype = hwloc_cache_type_by_depth_type(depth, ctype); @@ -5099,7 +5106,7 @@ look_sysfscpu(struct hwloc_topology *topology, /* get the cache size */ kB = 0; - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/size", i, j); /* contains %uK at least up to 4.19 */ + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/size", i, dirent->d_name); /* contains %uK at least up to 4.19 */ hwloc_read_path_as_uint(str, &kB, data->root_fd); /* KNL reports L3 with size=0 and full cpuset in cpuid. * Let hwloc_linux_try_add_knl_mcdram_cache() detect it better. @@ -5111,7 +5118,7 @@ look_sysfscpu(struct hwloc_topology *topology, /* get the line size */ linesize = 0; - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/coherency_line_size", i, j); /* contains %u at least up to 4.19 */ + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/coherency_line_size", i, dirent->d_name); /* contains %u at least up to 4.19 */ hwloc_read_path_as_uint(str, &linesize, data->root_fd); /* get the number of sets and lines per tag. @@ -5119,11 +5126,11 @@ look_sysfscpu(struct hwloc_topology *topology, * some archs (ia64, ppc) put 0 there when fully-associative, while others (x86) put something like -1 there. */ sets = 0; - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/number_of_sets", i, j); /* contains %u at least up to 4.19 */ + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/number_of_sets", i, dirent->d_name); /* contains %u at least up to 4.19 */ hwloc_read_path_as_uint(str, &sets, data->root_fd); lines_per_tag = 1; - sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/physical_line_partition", i, j); /* contains %u at least up to 4.19 */ + sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/physical_line_partition", i, dirent->d_name); /* contains %u at least up to 4.19 */ hwloc_read_path_as_uint(str, &lines_per_tag, data->root_fd); /* first cpu in this cache, add the cache */ @@ -5147,6 +5154,8 @@ look_sysfscpu(struct hwloc_topology *topology, } hwloc_bitmap_free(cacheset); } + closedir(cachesdir); + } } } hwloc_bitmap_foreach_end();