Skip to content

Commit 5258602

Browse files
committed
WIP linux/sysfs: use opendir() to list cpu caches
Instead of trying to open all "index%u" from 0 to 9. tests/hwloc/linux/gather must be update to ignore obj ID/gp_index because readdir() doesn't always get the caches in the expected order when loading from the sysfs dump. Refs #434 Signed-off-by: Brice Goglin <[email protected]>
1 parent 5fa11e1 commit 5258602

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

hwloc/topology-linux.c

+18-9
Original file line numberDiff line numberDiff line change
@@ -5032,11 +5032,18 @@ look_sysfscpu(struct hwloc_topology *topology,
50325032

50335033
/* look at the caches */
50345034
if (topology->want_some_cpu_caches) {
5035-
for(j=0; j<10; j++) {
5035+
DIR *cachesdir;
5036+
struct dirent *dirent;
5037+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/", i);
5038+
cachesdir = hwloc_opendir(str, data->root_fd);
5039+
if (cachesdir) {
5040+
while ((dirent = readdir(cachesdir)) != NULL) {
50365041
char str2[20]; /* enough for a level number (one digit) or a type (Data/Instruction/Unified) */
50375042
hwloc_bitmap_t cacheset;
50385043

5039-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/shared_cpu_map", i, j);
5044+
if (strncmp(dirent->d_name, "index", 5))
5045+
continue;
5046+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/shared_cpu_map", i, dirent->d_name);
50405047
cacheset = hwloc__alloc_read_path_as_cpumask(str, data->root_fd);
50415048
if (cacheset) {
50425049
if (hwloc_bitmap_iszero(cacheset)) {
@@ -5066,14 +5073,14 @@ look_sysfscpu(struct hwloc_topology *topology,
50665073
struct hwloc_obj *cache;
50675074

50685075
/* get the cache level depth */
5069-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/level", i, j); /* contains %u at least up to 4.19 */
5076+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/level", i, dirent->d_name); /* contains %u at least up to 4.19 */
50705077
if (hwloc_read_path_as_uint(str, &depth, data->root_fd) < 0) {
50715078
hwloc_bitmap_free(cacheset);
50725079
continue;
50735080
}
50745081

50755082
/* cache type */
5076-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/type", i, j);
5083+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/type", i, dirent->d_name);
50775084
if (hwloc_read_path_by_length(str, str2, sizeof(str2), data->root_fd) > 0) {
50785085
if (!strncmp(str2, "Data", 4))
50795086
ctype = HWLOC_OBJ_CACHE_DATA;
@@ -5084,7 +5091,7 @@ look_sysfscpu(struct hwloc_topology *topology,
50845091
}
50855092

50865093
/* cache id */
5087-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/id", i, j);
5094+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/id", i, dirent->d_name);
50885095
hwloc_read_path_as_uint(str, &id, data->root_fd);
50895096

50905097
otype = hwloc_cache_type_by_depth_type(depth, ctype);
@@ -5099,7 +5106,7 @@ look_sysfscpu(struct hwloc_topology *topology,
50995106

51005107
/* get the cache size */
51015108
kB = 0;
5102-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/size", i, j); /* contains %uK at least up to 4.19 */
5109+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/%s/size", i, dirent->d_name); /* contains %uK at least up to 4.19 */
51035110
hwloc_read_path_as_uint(str, &kB, data->root_fd);
51045111
/* KNL reports L3 with size=0 and full cpuset in cpuid.
51055112
* Let hwloc_linux_try_add_knl_mcdram_cache() detect it better.
@@ -5111,19 +5118,19 @@ look_sysfscpu(struct hwloc_topology *topology,
51115118

51125119
/* get the line size */
51135120
linesize = 0;
5114-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/coherency_line_size", i, j); /* contains %u at least up to 4.19 */
5121+
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 */
51155122
hwloc_read_path_as_uint(str, &linesize, data->root_fd);
51165123

51175124
/* get the number of sets and lines per tag.
51185125
* don't take the associativity directly in "ways_of_associativity" because
51195126
* some archs (ia64, ppc) put 0 there when fully-associative, while others (x86) put something like -1 there.
51205127
*/
51215128
sets = 0;
5122-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/number_of_sets", i, j); /* contains %u at least up to 4.19 */
5129+
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 */
51235130
hwloc_read_path_as_uint(str, &sets, data->root_fd);
51245131

51255132
lines_per_tag = 1;
5126-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cache/index%d/physical_line_partition", i, j); /* contains %u at least up to 4.19 */
5133+
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 */
51275134
hwloc_read_path_as_uint(str, &lines_per_tag, data->root_fd);
51285135

51295136
/* first cpu in this cache, add the cache */
@@ -5147,6 +5154,8 @@ look_sysfscpu(struct hwloc_topology *topology,
51475154
}
51485155
hwloc_bitmap_free(cacheset);
51495156
}
5157+
closedir(cachesdir);
5158+
}
51505159
}
51515160

51525161
} hwloc_bitmap_foreach_end();

0 commit comments

Comments
 (0)