mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-03-12 08:55:28 +00:00
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:
parent
0af7522e3e
commit
9281286181
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user