From 2248a61eff9dbde392d7fc091c8e7eb9b17fd622 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 | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/opal/mca/mpool/hugepage/mpool_hugepage_component.c b/opal/mca/mpool/hugepage/mpool_hugepage_component.c index 712301a38c5..5b6a557a476 100644 --- a/opal/mca/mpool/hugepage/mpool_hugepage_component.c +++ b/opal/mca/mpool/hugepage/mpool_hugepage_component.c @@ -209,7 +209,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) { @@ -223,6 +222,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; @@ -231,26 +242,20 @@ static void mca_mpool_hugepage_find_hugepages (void) { tok = strtok_r (opts, ",", &ctx); do { - if (0 == strncmp (tok, "pagesize", 8)) { - break; + if (NULL != tok && 0 == strncmp(tok, "pagesize", 8)) { + // 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 */