Skip to content

Commit

Permalink
Exit early in os::pd_pretouch_memory and generate a warning when user…
Browse files Browse the repository at this point in the history
… turns on UseMadvPopulteWrite when not supported
  • Loading branch information
limingliu-ampere committed Apr 8, 2024
1 parent fc8abd5 commit f5b7136
Showing 1 changed file with 35 additions and 33 deletions.
68 changes: 35 additions & 33 deletions src/hotspot/os/linux/os_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3040,33 +3040,34 @@ void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
}

size_t os::pd_pretouch_memory(void* first, void* last, size_t page_size) {
if (HugePages::thp_mode() != THPMode::always && UseTransparentHugePages) {
// No THP. Use the platform-independent pretouch memory code.
return page_size;
}

if (!UseMadvPopulateWrite) {
// Use small pages with the platform-independent pretouch memory code.
// When using THP, we need to always pre-touch using small pages as the
// OS will initially always use small pages.
return os::vm_page_size();
}

const size_t len = pointer_delta(last, first, sizeof(char)) + page_size;
// Use madvise to pretouch on Linux when THP is used, and fallback to the
// common method if unsupported. THP can form right after madvise rather than
// being assembled later.
if (HugePages::thp_mode() == THPMode::always || UseTransparentHugePages) {
int err = 0;
if (UseMadvPopulateWrite &&
::madvise(first, len, MADV_POPULATE_WRITE) == -1) {
err = errno;
}
if (!UseMadvPopulateWrite || err == EINVAL) { // Not to use or not supported
// When using THP we need to always pre-touch using small pages as the
// OS will initially always use small pages.
page_size = os::vm_page_size();
} else if (err == 0) {
page_size = 0;
}
if (UseMadvPopulateWrite) {
log_debug(gc, os)("Called madvise(" PTR_FORMAT ", " SIZE_FORMAT ", %d):"
" error='%s' (errno=%d), when THPMode::always=%d and"
" UseTransparentHugePages=%d",
p2i(first), len, MADV_POPULATE_WRITE, os::strerror(err),
err, (int)(HugePages::thp_mode() == THPMode::always),
(int)UseTransparentHugePages);
}
if (::madvise(first, len, MADV_POPULATE_WRITE) != -1) {
// Succeeded
// 0 signals not to run the platform-independent pretouch memory code.
return 0;
}
return page_size;

int err = errno;
log_debug(gc, os)("Called madvise(" PTR_FORMAT ", " SIZE_FORMAT ", %d):"
" error='%s' (errno=%d), when THPMode::always=%d and"
" UseTransparentHugePages=%d",
p2i(first), len, MADV_POPULATE_WRITE, os::strerror(err),
err, (int)(HugePages::thp_mode() == THPMode::always),
(int)UseTransparentHugePages);

return os::vm_page_size();
}

void os::numa_make_global(char *addr, size_t bytes) {
Expand Down Expand Up @@ -4544,6 +4545,7 @@ void os::init(void) {
(int(*)(pthread_t, const char*))dlsym(RTLD_DEFAULT, "pthread_setname_np");

check_pax();

Linux::version_init();

os::Posix::init();
Expand Down Expand Up @@ -4823,18 +4825,18 @@ jint os::init_2(void) {
}

// Check the availability of MADV_POPULATE_WRITE.
if (FLAG_IS_DEFAULT(UseMadvPopulateWrite) && UseMadvPopulateWrite) {
if (UseMadvPopulateWrite) {
// Some downstream kernels recognize MADV_POPULATE_WRITE_value as another
// advice, so the check of versions is required here.
// See https://github.com/oracle/linux-uek/issues/23
if (Linux::_release_major < 5 ||
(Linux::_release_major == 5 && Linux::_release_minor < 14)) {
FLAG_SET_DEFAULT(UseMadvPopulateWrite, false);
} else {
FLAG_SET_DEFAULT(UseMadvPopulateWrite, (::madvise(0, 0, MADV_POPULATE_WRITE) == 0));
}
bool supportMadvPopulateWrite =
(Linux::_release_major > 5 ||
(Linux::_release_major == 5 && Linux::_release_minor >= 14)) &&
(::madvise(0, 0, MADV_POPULATE_WRITE) == 0);
if (!FLAG_IS_DEFAULT(UseMadvPopulateWrite) && !supportMadvPopulateWrite)
warning("Platform is supposed not to support MADV_POPULATE_WRITE, "
"disabling using it to pretouch (-XX:-UseMadvPopulateWrite)");
}
log_debug(gc, os)("UseMadvPopulateWrite=%d", (int)(UseMadvPopulateWrite ? 1 : 0));

return JNI_OK;
}
Expand Down

0 comments on commit f5b7136

Please sign in to comment.