From 7e4499389e79d5dff9a5dcefdb417f01dae89d15 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Wed, 10 Jul 2024 03:15:25 -0700 Subject: [PATCH] [LibOS] Add `shared_cpu_list` file to sysfs cache info This is e.g. required by the gemm-common Rust crate, see `gemm-common/src/cache.rs`. Without this file, the crate logic incorrectly calculates shared-cpu count as zero and leads to a division-by-zero exception. Signed-off-by: Dmitrii Kuvaiskii --- libos/include/libos_fs_pseudo.h | 4 ++++ libos/src/fs/sys/cache_info.c | 14 +++++++++++++- libos/src/fs/sys/cpu_info.c | 2 +- libos/src/fs/sys/fs.c | 1 + libos/src/fs/sys/node_info.c | 2 +- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libos/include/libos_fs_pseudo.h b/libos/include/libos_fs_pseudo.h index 31883d67b1..d0b37cddf2 100644 --- a/libos/include/libos_fs_pseudo.h +++ b/libos/include/libos_fs_pseudo.h @@ -74,6 +74,10 @@ struct libos_dev_ops { * Note: Used to allocate on stack; increase with caution or use malloc instead. */ #define PAL_SYSFS_MAP_FILESZ 256 +/* Used to represent cpu ranges (lists) like "0-31,64-95,97". + * Note: Used to allocate on stack; increase with caution or use malloc instead. */ +#define PAL_SYSFS_RANGES_FILESZ 512 + /* * A node of the pseudo filesystem. A single node can describe either a single file, or a family of * files: diff --git a/libos/src/fs/sys/cache_info.c b/libos/src/fs/sys/cache_info.c index 6a58cf5e76..569d1aed57 100644 --- a/libos/src/fs/sys/cache_info.c +++ b/libos/src/fs/sys/cache_info.c @@ -44,7 +44,12 @@ int sys_cache_load(struct libos_dentry* dent, char** out_data, size_t* out_size) const struct pal_topo_info* topo = &g_pal_public_state->topo_info; size_t cache_idx = topo->threads[thread_id].ids_of_caches[cache_class]; const struct pal_cache_info* cache = &topo->caches[cache_idx]; - char str[PAL_SYSFS_MAP_FILESZ] = {'\0'}; + + /* str buffer of the same size is used for all below pseudo-files; we pick the largest size for + * this buffer (which is presumably the size required for the "shared_cpu_list" file) */ + static_assert(PAL_SYSFS_RANGES_FILESZ >= PAL_SYSFS_MAP_FILESZ, "sysfs file size too small"); + char str[PAL_SYSFS_RANGES_FILESZ] = {'\0'}; + if (strcmp(name, "shared_cpu_map") == 0) { struct callback_arg callback_arg = { .cache_id_to_match = cache_idx, @@ -52,6 +57,13 @@ int sys_cache_load(struct libos_dentry* dent, char** out_data, size_t* out_size) }; ret = sys_print_as_bitmask(str, sizeof(str), topo->threads_cnt, is_same_cache, &callback_arg); + } else if (strcmp(name, "shared_cpu_list") == 0) { + struct callback_arg callback_arg = { + .cache_id_to_match = cache_idx, + .cache_class = cache_class, + }; + ret = sys_print_as_ranges(str, sizeof(str), topo->threads_cnt, + is_same_cache, &callback_arg); } else if (strcmp(name, "level") == 0) { ret = snprintf(str, sizeof(str), "%zu\n", cache->level); } else if (strcmp(name, "type") == 0) { diff --git a/libos/src/fs/sys/cpu_info.c b/libos/src/fs/sys/cpu_info.c index 3719f47c67..cb084c8945 100644 --- a/libos/src/fs/sys/cpu_info.c +++ b/libos/src/fs/sys/cpu_info.c @@ -31,7 +31,7 @@ int sys_cpu_general_load(struct libos_dentry* dent, char** out_data, size_t* out int ret; const struct pal_topo_info* topo = &g_pal_public_state->topo_info; const char* name = dent->name; - char str[PAL_SYSFS_BUF_FILESZ]; + char str[PAL_SYSFS_RANGES_FILESZ]; if (strcmp(name, "online") == 0) { ret = sys_print_as_ranges(str, sizeof(str), topo->threads_cnt, is_online, NULL); diff --git a/libos/src/fs/sys/fs.c b/libos/src/fs/sys/fs.c index c6400f98f2..ff9f91e7cd 100644 --- a/libos/src/fs/sys/fs.c +++ b/libos/src/fs/sys/fs.c @@ -269,6 +269,7 @@ static void init_cpu_dir(struct pseudo_node* cpu) { indexX->list_names = &sys_resource_list_names; pseudo_add_str(indexX, "shared_cpu_map", &sys_cache_load); + pseudo_add_str(indexX, "shared_cpu_list", &sys_cache_load); pseudo_add_str(indexX, "level", &sys_cache_load); pseudo_add_str(indexX, "type", &sys_cache_load); pseudo_add_str(indexX, "size", &sys_cache_load); diff --git a/libos/src/fs/sys/node_info.c b/libos/src/fs/sys/node_info.c index 5116558151..23da9584f9 100644 --- a/libos/src/fs/sys/node_info.c +++ b/libos/src/fs/sys/node_info.c @@ -30,7 +30,7 @@ int sys_node_general_load(struct libos_dentry* dent, char** out_data, size_t* ou int ret; const struct pal_topo_info* topo = &g_pal_public_state->topo_info; const char* name = dent->name; - char str[PAL_SYSFS_BUF_FILESZ]; + char str[PAL_SYSFS_RANGES_FILESZ]; if (strcmp(name, "online") == 0) { ret = sys_print_as_ranges(str, sizeof(str), topo->numa_nodes_cnt, is_online, NULL); } else if (strcmp(name, "possible") == 0) {