Explorar o código

HPCC-21167 Report in logs if transparent_hugepage/enabled is set to always

* Also ensure pages are returned to the system in multiples of huge page size
  if transparent_hugepage/enabled set to always

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday %!s(int64=6) %!d(string=hai) anos
pai
achega
f0a5c20829
Modificáronse 3 ficheiros con 29 adicións e 5 borrados
  1. 12 1
      roxie/roxiemem/roxiemem.cpp
  2. 14 3
      system/jlib/jdebug.cpp
  3. 3 1
      system/jlib/jdebug.hpp

+ 12 - 1
roxie/roxiemem/roxiemem.cpp

@@ -292,8 +292,19 @@ static void initializeHeap(bool allowHugePages, bool allowTransparentHugePages,
     if (!heapBase)
     {
         const memsize_t hugePageSize = getHugePageSize();
-        bool useTransparentHugePages = allowTransparentHugePages && areTransparentHugePagesEnabled();
+        HugePageMode mode = queryTransparentHugePagesMode();
+        bool hasTransparenHugePages = areTransparentHugePagesEnabled(mode);
+        bool useTransparentHugePages = allowTransparentHugePages && hasTransparenHugePages;
         memsize_t heapAlignment = useTransparentHugePages ? hugePageSize : HEAP_ALIGNMENT_SIZE;
+        if (mode == HugePageMode::Always)
+        {
+            //Always return memory in multiples of the huge page size - even if it is not being used
+            heapAlignment = hugePageSize;
+            OERRLOG("WARNING: The OS is configured to always use transparent huge pages.  This may cause unexplained pauses "
+                    "while transparent huge pages are coalesced. The recommended setting for "
+                    "/sys/kernel/mm/transparent_hugepage/enabled is madvise");
+        }
+
         if (heapAlignment < HEAP_ALIGNMENT_SIZE)
             heapAlignment = HEAP_ALIGNMENT_SIZE;
 

+ 14 - 3
system/jlib/jdebug.cpp

@@ -3194,21 +3194,32 @@ void PrintMemoryReport(bool full)
 #endif
 
 
-bool areTransparentHugePagesEnabled()
+bool areTransparentHugePagesEnabled(HugePageMode mode)
+{
+    return (mode != HugePageMode::Never) && (mode != HugePageMode::Unknown);
+}
+
+HugePageMode queryTransparentHugePagesMode()
 {
 #ifdef __linux__
     StringBuffer contents;
     try
     {
         contents.loadFile("/sys/kernel/mm/transparent_hugepage/enabled");
-        return !strstr(contents.str(), "[never]");
+        if (strstr(contents.str(), "[never]"))
+            return HugePageMode::Never;
+        if (strstr(contents.str(), "[madvise]"))
+            return HugePageMode::Madvise;
+        if (strstr(contents.str(), "[always]"))
+            return HugePageMode::Always;
     }
     catch (IException * e)
     {
         e->Release();
     }
+    return HugePageMode::Unknown;
 #endif
-    return false;
+    return HugePageMode::Never;
 }
 
 memsize_t getHugePageSize()

+ 3 - 1
system/jlib/jdebug.hpp

@@ -333,6 +333,7 @@ unsigned jlib_decl setAllocHook(bool on);  // bwd compat returns unsigned
  #define USE_JLIB_ALLOC_HOOK
 #endif
 
+enum class HugePageMode { Always, Madvise, Never, Unknown };
 extern jlib_decl void getHardwareInfo(HardwareInfo &hdwInfo, const char *primDiskPath = NULL, const char *secDiskPath = NULL);
 extern jlib_decl void getProcessTime(UserSystemTime_t & time);
 extern jlib_decl memsize_t getMapInfo(const char *type);
@@ -345,7 +346,8 @@ extern jlib_decl void clearAffinityCache(); // should be called whenever the pro
 extern jlib_decl void printProcMap(const char *fn, bool printbody, bool printsummary, StringBuffer *lnout, MemoryBuffer *mb, bool useprintf);
 extern jlib_decl void PrintMemoryReport(bool full=true);
 extern jlib_decl void printAllocationSummary();
-extern jlib_decl bool areTransparentHugePagesEnabled();
+extern jlib_decl bool areTransparentHugePagesEnabled(HugePageMode mode);
+extern jlib_decl HugePageMode queryTransparentHugePagesMode();
 extern jlib_decl memsize_t getHugePageSize();
 
 #endif