Enable huge page for posix platforms (#825)

This patch enables huge page support for posix platforms for performance
reason, if the request size to mmap is larger than 2MB, then we use madvise
to set some pages to huge page.
And add macro control to enable tracing the mmap/munmap.

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang 2021-11-12 16:19:26 +08:00 committed by GitHub
parent 0af7522e3e
commit 9281286181
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,24 +5,56 @@
#include "platform_api_vmcore.h"
#ifndef BH_ENABLE_TRACE_MMAP
#define BH_ENABLE_TRACE_MMAP 0
#endif
#if BH_ENABLE_TRACE_MMAP != 0
static size_t total_size_mmapped = 0;
static size_t total_size_munmapped = 0;
#endif
#define HUGE_PAGE_SIZE (2 * 1024 * 1024)
static inline uintptr_t
round_up(uintptr_t v, uintptr_t b)
{
uintptr_t m = b - 1;
return (v + m) & ~m;
}
static inline uintptr_t
round_down(uintptr_t v, uintptr_t b)
{
uintptr_t m = b - 1;
return v & ~m;
}
void *
os_mmap(void *hint, size_t size, int prot, int flags)
{
int map_prot = PROT_NONE;
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
uint64 request_size, page_size;
uint8 *addr;
uint8 *addr = MAP_FAILED;
uint32 i;
page_size = (uint64)getpagesize();
request_size = (size + page_size - 1) & ~(page_size - 1);
#if !defined(__APPLE__) && !defined(__NuttX__)
/* huge page isn't supported on MacOS and NuttX */
if (request_size >= HUGE_PAGE_SIZE)
/* apply one extra huge page */
request_size += HUGE_PAGE_SIZE;
#endif
if ((size_t)request_size < size)
/* integer overflow */
return NULL;
if (request_size > 16 * (uint64)UINT32_MAX)
/* At most 16 G is allowed */
/* at most 16 G is allowed */
return NULL;
if (prot & MMAP_PROT_READ)
@ -80,25 +112,93 @@ os_mmap(void *hint, size_t size, int prot, int flags)
os_munmap(addr, request_size);
}
else {
/* reset next hint address */
/* success, reset next hint address */
hint_addr += request_size;
return addr;
break;
}
}
hint_addr += BH_MB;
}
}
#endif
#endif /* end of BUILD_TARGET_RISCV64_LP64D || BUILD_TARGET_RISCV64_LP64 */
/* try 5 times */
for (i = 0; i < 5; i++) {
addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED)
break;
/* memory has't been mapped or was mapped failed previously */
if (addr == MAP_FAILED) {
/* try 5 times */
for (i = 0; i < 5; i++) {
addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED)
break;
}
}
if (addr == MAP_FAILED)
if (addr == MAP_FAILED) {
#if BH_ENABLE_TRACE_MMAP != 0
os_printf("mmap failed\n");
#endif
return NULL;
}
#if BH_ENABLE_TRACE_MMAP != 0
total_size_mmapped += request_size;
os_printf("mmap return: %p with size: %zu, total_size_mmapped: %zu, "
"total_size_munmapped: %zu\n",
addr, request_size, total_size_mmapped, total_size_munmapped);
#endif
#if !defined(__APPLE__) && !defined(__NuttX__)
/* huge page isn't supported on MacOS and NuttX */
if (request_size > HUGE_PAGE_SIZE) {
uintptr_t huge_start, huge_end;
size_t prefix_size = 0, suffix_size = HUGE_PAGE_SIZE;
huge_start = round_up((uintptr_t)addr, HUGE_PAGE_SIZE);
if (huge_start > (uintptr_t)addr) {
prefix_size += huge_start - (uintptr_t)addr;
suffix_size -= huge_start - (uintptr_t)addr;
}
/* unmap one extra huge page */
if (prefix_size > 0) {
munmap(addr, prefix_size);
#if BH_ENABLE_TRACE_MMAP != 0
total_size_munmapped += prefix_size;
os_printf("munmap %p with size: %zu, total_size_mmapped: %zu, "
"total_size_munmapped: %zu\n",
addr, prefix_size, total_size_mmapped,
total_size_munmapped);
#endif
}
if (suffix_size > 0) {
munmap(addr + request_size - suffix_size, suffix_size);
#if BH_ENABLE_TRACE_MMAP != 0
total_size_munmapped += suffix_size;
os_printf("munmap %p with size: %zu, total_size_mmapped: %zu, "
"total_size_munmapped: %zu\n",
addr + request_size - suffix_size, suffix_size,
total_size_mmapped, total_size_munmapped);
#endif
}
addr = (uint8 *)huge_start;
request_size -= HUGE_PAGE_SIZE;
huge_end = round_down(huge_start + request_size, HUGE_PAGE_SIZE);
if (huge_end > huge_start) {
int ret = madvise((void *)huge_start, huge_end - huge_start,
MADV_HUGEPAGE);
if (ret) {
#if BH_ENABLE_TRACE_MMAP != 0
os_printf(
"warning: madvise(%p, %lu) huge page failed, return %d\n",
(void *)huge_start, huge_end - huge_start, ret);
#endif
}
}
}
#endif /* end of __APPLE__ || __NuttX__ */
return addr;
}
@ -113,7 +213,14 @@ os_munmap(void *addr, size_t size)
if (munmap(addr, request_size)) {
os_printf("os_munmap error addr:%p, size:0x%" PRIx64 ", errno:%d\n",
addr, request_size, errno);
return;
}
#if BH_ENABLE_TRACE_MMAP != 0
total_size_munmapped += request_size;
os_printf("munmap %p with size: %zu, total_size_mmapped: %zu, "
"total_size_munmapped: %zu\n",
addr, request_size, total_size_mmapped, total_size_munmapped);
#endif
}
}