diff --git a/bolt/runtime/hugify.cpp b/bolt/runtime/hugify.cpp --- a/bolt/runtime/hugify.cpp +++ b/bolt/runtime/hugify.cpp @@ -60,7 +60,7 @@ /// Check whether the kernel supports THP via corresponding sysfs entry. /// thp works only starting from 5.10 -static bool hasPagecacheTHPSupport() { +static bool isTHPEnabled() { char Buf[64]; int FD = __open("/sys/kernel/mm/transparent_hugepage/enabled", @@ -68,7 +68,7 @@ if (FD < 0) return false; - memset(Buf, 0, sizeof(Buf)); + Buf[0] = '\0'; const size_t Res = __read(FD, Buf, sizeof(Buf)); if (Res < 0) return false; @@ -76,6 +76,10 @@ if (!strStr(Buf, "[always]") && !strStr(Buf, "[madvise]")) return false; + return true; +} + +static bool isKernelSupportTHP() { struct KernelVersionTy { uint32_t major; uint32_t minor; @@ -85,8 +89,36 @@ KernelVersionTy KernelVersion; getKernelVersion((uint32_t *)&KernelVersion); - if (KernelVersion.major >= 5 && KernelVersion.minor >= 10) - return true; + if (KernelVersion.major < 5 || KernelVersion.minor < 10) + return false; + + int FD = __open("/boot/config", 0 /* O_RDONLY */, 0); + if (FD < 0) + return false; + + char Buf[128]; + char ch; + uint64_t i = 0; + const uint64_t num = sizeof("CONFIG_"); + void *pRes; + Buf[0] = '\0'; + while(__read(FD, Buf, num) > 0) { + i = num; + while (__read(FD, &ch, 1) > 0 && ch != '\n') + Buf[i++] = ch; + + pRes = strStr(Buf, "CONFIG_READ_ONLY_THP_FOR_FS"); + if (pRes) { + // OFF: # CONFIG_READ_ONLY_THP_FOR_FS is not + // ON: CONFIG_READ_ONLY_THP_FOR_FS=y + DEBUG(report(Buf)); + const char *p = (char *)pRes + sizeof("CONFIG_READ_ONLY_THP_FOR_FS"); + if (*p == 'y') + return true; + return false; + } + Buf[0] = '\0'; + } return false; } @@ -150,13 +182,18 @@ DEBUG(reportNumber("[hugify] aligned huge page from: ", (uint64_t)From, 16);) DEBUG(reportNumber("[hugify] aligned huge page to: ", (uint64_t)To, 16);) - if (!hasPagecacheTHPSupport()) { + if (!isTHPEnabled()) { DEBUG(report( - "[hugify] workaround with memory alignment for kernel < 5.10\n");) - hugifyForOldKernel(From, To); + "[hugify] THP is disabled, please check /sys/kernel/mm/transparent_hugepage/enabled\n");) return; } + if (!isKernelSupportTHP()) { + DEBUG(report( + "[hugify] workaround with memory alignment for kernel < 5.10\n");) + hugifyForOldKernel(From, To); + } + if (__madvise(From, (To - From), 14 /* MADV_HUGEPAGE */) == -1) { char Msg[] = "[hugify] failed to allocate large page\n"; // TODO: allow user to control the failure behavior.