diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index de26adf136eef..f58bc0951a676 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -176,7 +176,9 @@ pthread_t os::Linux::_main_thread; bool os::Linux::_supports_fast_thread_cpu_time = false; const char * os::Linux::_libc_version = nullptr; const char * os::Linux::_libpthread_version = nullptr; - +long os::Linux::_release_major = -1; +long os::Linux::_release_minor = -1; +bool os::Linux::_is_uek_release{false}; bool os::Linux::_thp_requested{false}; #ifdef __GLIBC__ @@ -367,10 +369,7 @@ static void next_line(FILE *f) { } while (c != '\n' && c != EOF); } -void os::Linux::kernel_version(long* major, long* minor) { - *major = -1; - *minor = -1; - +void os::Linux::version_init() { struct utsname buffer; int ret = uname(&buffer); if (ret != 0) { @@ -379,15 +378,24 @@ void os::Linux::kernel_version(long* major, long* minor) { } char* walker = buffer.release; - long* set_v = major; - while (*minor == -1 && walker != nullptr) { + long* set_v = &_release_major; + while (_release_minor == -1 && walker != nullptr) { if (isdigit(walker[0])) { *set_v = strtol(walker, &walker, 10); - set_v = minor; + set_v = &_release_minor; } else { ++walker; } } + + while ((walker = strstr(walker, ".el"))) { + if (sscanf(walker, ".el%duek.", &ret) == 1) { + _is_uek_release = true; + break; + } else { + walker += 3; + } + } } bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu) { @@ -3066,13 +3074,18 @@ size_t os::pd_pretouch_memory(void* first, void* last, size_t page_size) { 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. - return os::vm_page_size(); - } else if (err != 0) { - log_info(gc, os)("::madvise(" PTR_FORMAT ", " SIZE_FORMAT ", %d) failed; " - "error='%s' (errno=%d)", p2i(first), len, - MADV_POPULATE_WRITE, os::strerror(err), err); + 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); } - return 0; } return page_size; } @@ -4552,9 +4565,7 @@ void os::init(void) { (int(*)(pthread_t, const char*))dlsym(RTLD_DEFAULT, "pthread_setname_np"); check_pax(); - - // Check the availability of MADV_POPULATE_WRITE. - FLAG_SET_DEFAULT(UseMadvPopulateWrite, (::madvise(0, 0, MADV_POPULATE_WRITE) == 0)); + Linux::version_init(); os::Posix::init(); } @@ -4832,6 +4843,16 @@ jint os::init_2(void) { } } + // Check the availability of MADV_POPULATE_WRITE. + if (FLAG_IS_DEFAULT(UseMadvPopulateWrite) && UseMadvPopulateWrite) { + // Some uek releases recognize MADV_POPULATE_WRITE_value as another advice, + // so a trick for uek releases is required. + // See https://github.com/oracle/linux-uek/issues/23 + const int flag = MADV_POPULATE_WRITE + (os::Linux::_is_uek_release ? 1 : 0); + FLAG_SET_DEFAULT(UseMadvPopulateWrite, (::madvise(0, 0, flag) == 0)); + } + log_debug(gc, os)("UseMadvPopulateWrite=%d", (int)(UseMadvPopulateWrite ? 1 : 0)); + return JNI_OK; } diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 6b902e8280244..49dbd81a2fa7c 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -43,6 +43,9 @@ class os::Linux { static const char *_libc_version; static const char *_libpthread_version; + static long _release_major; + static long _release_minor; + static bool _supports_fast_thread_cpu_time; static GrowableArray* _cpu_to_node; @@ -52,6 +55,7 @@ class os::Linux { protected: + static bool _is_uek_release; static julong _physical_memory; static pthread_t _main_thread; @@ -66,6 +70,7 @@ class os::Linux { static int commit_memory_impl(char* addr, size_t bytes, size_t alignment_hint, bool exec); + static void version_init(); static void set_libc_version(const char *s) { _libc_version = s; } static void set_libpthread_version(const char *s) { _libpthread_version = s; } @@ -93,7 +98,10 @@ class os::Linux { bool has_steal_ticks; }; - static void kernel_version(long* major, long* minor); + static void kernel_version(long* major, long* minor) { + *major = _release_major; + *minor = _release_minor; + } // which_logical_cpu=-1 returns accumulated ticks for all cpus. static bool get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu); diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 24508d4cb80c5..8d6f34775057c 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -112,7 +112,6 @@ runtime/ErrorHandling/TestDwarf.java#checkDecoder 8305489 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x64 runtime/os/TestTransparentHugePageUsage.java 8324776 linux-all -runtime/Thread/TestAlwaysPreTouchStacks.java 8324781 linux-all applications/jcstress/accessAtomic.java 8325984 generic-all applications/jcstress/acqrel.java 8325984 generic-all