From 30689bfe45f4d15e927626bcd36fee1ff8ba5235 Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Mon, 28 Apr 2025 20:58:56 -0400 Subject: [PATCH] mpool/hugepage: fix sizing of hugepages Really old code was still preferring to parse Linux's /proc/mounts to find the size of hugepages instead of just using statfs() or statvfs() to get the size directly. Thanks to @wangshaochuang for noticing that the parsing of /proc/mounts wasn't even quite right in modern Linux systems, we have changed the preference in the code to use statfs() / statvfs() if available (which it almost certainly will be), and only fall back to parsing /proc/mounts on really, really, really old systems (where the /proc/mounts parsing will likely be correct). Signed-off-by: Jeff Squyres (cherry picked from commit 8f34fb88c4f81db01f06b5c149b5b14b8955dbf0) --- .../mpool/hugepage/mpool_hugepage_component.c | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/opal/mca/mpool/hugepage/mpool_hugepage_component.c b/opal/mca/mpool/hugepage/mpool_hugepage_component.c index 888562e65f2..191fc405e7b 100644 --- a/opal/mca/mpool/hugepage/mpool_hugepage_component.c +++ b/opal/mca/mpool/hugepage/mpool_hugepage_component.c @@ -218,7 +218,6 @@ static void mca_mpool_hugepage_find_hugepages(void) mca_mpool_hugepage_hugepage_t *hp; FILE *fh; struct mntent *mntent; - char *opts, *tok, *ctx; fh = setmntent("/proc/mounts", "r"); if (NULL == fh) { @@ -232,6 +231,18 @@ static void mca_mpool_hugepage_find_hugepages(void) continue; } +#if defined(USE_STATFS) + struct statfs info; + statfs(mntent->mnt_dir, &info); + page_size = info.f_bsize; +#elif defined(HAVE_STATVFS) + struct statvfs info; + statvfs(mntent->mnt_dir, &info); + page_size = info.f_bsize; +#else + // Fallback for extremely old systems that do not have + // statfs(). + char *opts, *tok, *ctx; opts = strdup(mntent->mnt_opts); if (NULL == opts) { break; @@ -240,25 +251,19 @@ static void mca_mpool_hugepage_find_hugepages(void) tok = strtok_r(opts, ",", &ctx); do { if (NULL != tok && 0 == strncmp(tok, "pagesize", 8)) { - break; + // It is expected that pagesize=X will be an integer + // number with no units qualifier following it. + // Specifically: Linux circa 2025 has /proc/mounts + // output like "... rw,relatime,pagesize=2M". But if + // your system is signifncantly older than that + // (statfs() was introduced around 1994), we're + // assuming that there is no units qualifier. + (void) sscanf(tok, "pagesize=%lu", &page_size); } tok = strtok_r(NULL, ",", &ctx); } while (tok); - - if (!tok) { -# if defined(USE_STATFS) - struct statfs info; - - statfs(mntent->mnt_dir, &info); -# elif defined(HAVE_STATVFS) - struct statvfs info; - statvfs(mntent->mnt_dir, &info); -# endif - page_size = info.f_bsize; - } else { - (void) sscanf(tok, "pagesize=%lu", &page_size); - } free(opts); +#endif if (0 == page_size) { /* could not get page size */