From: Christian Goeschel Ndjomouo Date: Fri, 20 Feb 2026 00:02:09 +0000 (-0500) Subject: lsmem: fix missing zone info when memory blocks start at an index other than 0 X-Git-Tag: v2.43-devel~54^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8c48ab84d508223631fffab6403d4607a41ef8c;p=thirdparty%2Futil-linux.git lsmem: fix missing zone info when memory blocks start at an index other than 0 On systems that have an uncommon physical memory layout, e.g. where hotpluggable memory blocks start at an offset greater than 0, we failed to set the 'have_zones' control flag, which caused an omission of the ZONES information of the listed individual memory block or a block range. This is because we explicitly tested for /sys/devices/system/memory/memory0/valid_zones, however it is better to simply look for any memory directory entry and validate the existence of the valid_zones attribute. Closes: #4055 Signed-off-by: Christian Goeschel Ndjomouo --- diff --git a/sys-utils/lsmem.c b/sys-utils/lsmem.c index 79d90ff55..c68f2317c 100644 --- a/sys-utils/lsmem.c +++ b/sys-utils/lsmem.c @@ -422,6 +422,25 @@ static int memory_block_get_node(struct lsmem *lsmem, char *name) return node; } +static int memory_block_has_zones(struct lsmem *lsmem, char *name) +{ + char *path = NULL; + int rc; + + if (!name) + return -EINVAL; + + xasprintf(&path, "%s/valid_zones", name); + rc = ul_path_access(lsmem->sysmem, F_OK, path); + if (rc != 0) { + free(path); + return rc; + } + + free(path); + return 0; +} + static int memory_block_read_attrs(struct lsmem *lsmem, char *name, struct memory_block *blk) { @@ -611,9 +630,23 @@ static void read_basic_info(struct lsmem *lsmem) } } - /* The valid_zones sysmem attribute was introduced with kernel 3.18 */ - if (ul_path_access(lsmem->sysmem, F_OK, "memory0/valid_zones") == 0) - lsmem->have_zones = 1; + /* The valid_zones sysmem attribute was introduced with kernel 3.18. + * + * Note that some systems can have different physical memory layouts which + * make it so that the first hotpluggable memory block starts with an ID + * other than 0. Therefore, we have to walk through the sysmem dir and + * find the memory/ entries and test whether the valid_zones attribute + * is available. + */ + for (i = 0; i < lsmem->ndirs; i++) { + if (strncmp("memory", lsmem->dirs[i]->d_name, 6) != 0) + continue; + + if (memory_block_has_zones(lsmem, lsmem->dirs[i]->d_name) == 0) { + lsmem->have_zones = 1; + break; + } + } } static void __attribute__((__noreturn__)) usage(void)