Skip to content

Commit 1ab104e

Browse files
committed
linux, checking THP current system settings.
1 parent 36edfbc commit 1ab104e

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/os.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ static size_t os_alloc_granularity = 4096;
9797
// if non-zero, use large page allocation
9898
static size_t large_os_page_size = 0;
9999

100+
#if defined(MADV_HUGEPAGE)
101+
// only linux supports the THP's notion.
102+
static bool os_transparent_huge_pages = false;
103+
#endif
104+
100105
// is memory overcommit allowed?
101106
// set dynamically in _mi_os_init (and if true we use MAP_NORESERVE)
102107
static bool os_overcommit = true;
@@ -237,13 +242,37 @@ void _mi_os_init() {
237242

238243
#else // generic unix
239244

245+
static void os_detect_transparent_huge_pages(void) {
246+
#if defined(MADV_HUGEPAGE)
247+
int fd = -1;
248+
size_t i;
249+
static const char *paths[] = {
250+
"/sys/kernel/mm/transparent_hugepage/enabled",
251+
"/sys/kernel/mm/redhat_transparent_hugepage/enabled",
252+
};
253+
254+
for (i = 0; i < sizeof(paths) / sizeof(paths[0]); i ++) {
255+
fd = open(paths[i], O_RDONLY);
256+
if (fd > 0) break;
257+
}
258+
259+
if (fd < 0) return;
260+
char buf[128];
261+
ssize_t nread = read(fd, &buf, sizeof(buf));
262+
close(fd);
263+
if (nread >= 1) {
264+
if (strstr(buf, "[madvise]")) os_transparent_huge_pages = true;
265+
}
266+
#endif
267+
}
268+
240269
static void os_detect_overcommit(void) {
241270
#if defined(__linux__)
242271
int fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY);
243-
if (fd < 0) return;
272+
if (fd < 0) return;
244273
char buf[128];
245274
ssize_t nread = read(fd, &buf, sizeof(buf));
246-
close(fd);
275+
close(fd);
247276
// <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>
248277
// 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE)
249278
if (nread >= 1) {
@@ -269,6 +298,7 @@ void _mi_os_init() {
269298
}
270299
large_os_page_size = 2*MI_MiB; // TODO: can we query the OS for this?
271300
os_detect_overcommit();
301+
os_detect_transparent_huge_pages();
272302
}
273303
#endif
274304

@@ -542,7 +572,7 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
542572
// in that case -- in particular for our large regions (in `memory.c`).
543573
// However, some systems only allow THP if called with explicit `madvise`, so
544574
// when large OS pages are enabled for mimalloc, we call `madvise` anyways.
545-
if (allow_large && use_large_os_page(size, try_alignment)) {
575+
if (os_transparent_huge_pages && allow_large && use_large_os_page(size, try_alignment)) {
546576
if (madvise(p, size, MADV_HUGEPAGE) == 0) {
547577
*is_large = true; // possibly
548578
};

0 commit comments

Comments
 (0)