From 4029007b7edd290c236901a246ef48ac3e9de4b6 Mon Sep 17 00:00:00 2001 From: Mukul Sabharwal Date: Fri, 19 Apr 2019 14:54:35 -0700 Subject: [PATCH] Large Pages on Linux & macOS (#24098) --- src/gc/unix/config.h.in | 1 + src/gc/unix/configure.cmake | 9 +++++++++ src/gc/unix/gcenv.unix.cpp | 2 ++ src/pal/src/config.h.in | 2 ++ src/pal/src/configure.cmake | 16 ++++++++++++++++ src/pal/src/map/virtual.cpp | 29 ++++++++++++++++++++++------- 6 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/gc/unix/config.h.in b/src/gc/unix/config.h.in index 99866cd..7f4d8d7 100644 --- a/src/gc/unix/config.h.in +++ b/src/gc/unix/config.h.in @@ -9,6 +9,7 @@ #cmakedefine01 HAVE_SYS_MMAN_H #cmakedefine01 HAVE_PTHREAD_THREADID_NP #cmakedefine01 HAVE_PTHREAD_GETTHREADID_NP +#cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY #cmakedefine01 HAVE_MAP_HUGETLB #cmakedefine01 HAVE_SCHED_GETCPU #cmakedefine01 HAVE_NUMA_H diff --git a/src/gc/unix/configure.cmake b/src/gc/unix/configure.cmake index 2e31766..3e478c4 100644 --- a/src/gc/unix/configure.cmake +++ b/src/gc/unix/configure.cmake @@ -29,6 +29,15 @@ check_cxx_source_compiles(" int main() { + return VM_FLAGS_SUPERPAGE_SIZE_ANY; + } + " HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY) + +check_cxx_source_compiles(" + #include + + int main() + { return MAP_HUGETLB; } " HAVE_MAP_HUGETLB) diff --git a/src/gc/unix/gcenv.unix.cpp b/src/gc/unix/gcenv.unix.cpp index edddee1..c248082 100644 --- a/src/gc/unix/gcenv.unix.cpp +++ b/src/gc/unix/gcenv.unix.cpp @@ -551,6 +551,8 @@ void* GCToOSInterface::VirtualReserveAndCommitLargePages(size_t size) { #if HAVE_MAP_HUGETLB uint32_t largePagesFlag = MAP_HUGETLB; +#elif HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY + uint32_t largePagesFlag = VM_FLAGS_SUPERPAGE_SIZE_ANY; #else uint32_t largePagesFlag = 0; #endif diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in index d0e14df..3ceb180 100644 --- a/src/pal/src/config.h.in +++ b/src/pal/src/config.h.in @@ -1,6 +1,8 @@ #ifndef _PAL_CONFIG_H_INCLUDED #define _PAL_CONFIG_H_INCLUDED 1 +#cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY +#cmakedefine01 HAVE_MAP_HUGETLB #cmakedefine01 HAVE_IEEEFP_H #cmakedefine01 HAVE_SYS_VMPARAM_H #cmakedefine01 HAVE_MACH_VM_TYPES_H diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake index a4d550e..a991e75 100644 --- a/src/pal/src/configure.cmake +++ b/src/pal/src/configure.cmake @@ -45,6 +45,22 @@ endif() set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS}) check_cxx_source_compiles(" +#include +int main() +{ + return VM_FLAGS_SUPERPAGE_SIZE_ANY; +} +" HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY) + +check_cxx_source_compiles(" +#include +int main() +{ + return MAP_HUGETLB; +} +" HAVE_MAP_HUGETLB) + +check_cxx_source_compiles(" #include int main(int argc, char **argv) { return 0; diff --git a/src/pal/src/map/virtual.cpp b/src/pal/src/map/virtual.cpp index 4dae9f3..ff5cde9 100644 --- a/src/pal/src/map/virtual.cpp +++ b/src/pal/src/map/virtual.cpp @@ -70,7 +70,8 @@ Function: static LPVOID ReserveVirtualMemory( IN CPalThread *pthrCurrent, /* Currently executing thread */ IN LPVOID lpAddress, /* Region to reserve or commit */ - IN SIZE_T dwSize); /* Size of Region */ + IN SIZE_T dwSize, /* Size of Region */ + IN DWORD fAllocationType); /* Allocation Type */ // A memory allocator that allocates memory from a pre-reserved region @@ -915,7 +916,7 @@ static LPVOID VIRTUALReserveMemory( if (pRetVal == NULL) { // Try to reserve memory from the OS - pRetVal = ReserveVirtualMemory(pthrCurrent, (LPVOID)StartBoundary, MemSize); + pRetVal = ReserveVirtualMemory(pthrCurrent, (LPVOID)StartBoundary, MemSize, flAllocationType); } if (pRetVal != NULL) @@ -958,7 +959,8 @@ static LPVOID VIRTUALReserveMemory( static LPVOID ReserveVirtualMemory( IN CPalThread *pthrCurrent, /* Currently executing thread */ IN LPVOID lpAddress, /* Region to reserve or commit */ - IN SIZE_T dwSize) /* Size of Region */ + IN SIZE_T dwSize, /* Size of Region */ + IN DWORD fAllocationType) /* Allocation type */ { UINT_PTR StartBoundary = (UINT_PTR)lpAddress; SIZE_T MemSize = dwSize; @@ -986,6 +988,19 @@ static LPVOID ReserveVirtualMemory( mmapFlags |= MAP_FIXED; #endif // HAVE_VM_ALLOCATE + if ((fAllocationType & MEM_LARGE_PAGES) != 0) + { +#if HAVE_MAP_HUGETLB + mmapFlags |= MAP_HUGETLB; + TRACE("MAP_HUGETLB flag set\n"); +#elif HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY + mmapFlags |= VM_FLAGS_SUPERPAGE_SIZE_ANY; + TRACE("VM_FLAGS_SUPERPAGE_SIZE_ANY flag set\n"); +#else + TRACE("Large Pages requested, but not supported in this PAL configuration\n"); +#endif + } + mmapFlags |= MAP_ANON | MAP_PRIVATE; LPVOID pRetVal = mmap((LPVOID) StartBoundary, @@ -1338,10 +1353,10 @@ VirtualAlloc( } /* Test for un-supported flags. */ - if ( ( flAllocationType & ~( MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_TOP_DOWN | MEM_RESERVE_EXECUTABLE ) ) != 0 ) + if ( ( flAllocationType & ~( MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_TOP_DOWN | MEM_RESERVE_EXECUTABLE | MEM_LARGE_PAGES ) ) != 0 ) { ASSERT( "flAllocationType can be one, or any combination of MEM_COMMIT, \ - MEM_RESERVE, MEM_TOP_DOWN, or MEM_RESERVE_EXECUTABLE.\n" ); + MEM_RESERVE, MEM_TOP_DOWN, MEM_RESERVE_EXECUTABLE, or MEM_LARGE_PAGES.\n" ); pthrCurrent->SetLastError( ERROR_INVALID_PARAMETER ); goto done; } @@ -2145,7 +2160,7 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory() // Do actual memory reservation. do { - m_startAddress = ReserveVirtualMemory(pthrCurrent, (void*)preferredStartAddress, sizeOfAllocation); + m_startAddress = ReserveVirtualMemory(pthrCurrent, (void*)preferredStartAddress, sizeOfAllocation, 0 /* fAllocationType */); if (m_startAddress != nullptr) { break; @@ -2175,7 +2190,7 @@ void ExecutableMemoryAllocator::TryReserveInitialMemory() // - The code heap allocator for the JIT can allocate from this address space. Beyond this reservation, one can use // the COMPlus_CodeHeapReserveForJumpStubs environment variable to reserve space for jump stubs. sizeOfAllocation = MaxExecutableMemorySize; - m_startAddress = ReserveVirtualMemory(pthrCurrent, nullptr, sizeOfAllocation); + m_startAddress = ReserveVirtualMemory(pthrCurrent, nullptr, sizeOfAllocation, 0 /* fAllocationType */); if (m_startAddress == nullptr) { return; -- 2.7.4