From a1fd5f4e88f52125eef4feea91a60641981177c1 Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Mon, 27 Jan 2025 07:13:00 +0000 Subject: [PATCH] 8348554: Enhance Linux kernel version checks Reviewed-by: shade, fyang --- src/hotspot/os/linux/os_linux.cpp | 30 +++++++++++++++---- src/hotspot/os/linux/os_linux.hpp | 8 ++++- .../os/linux/systemMemoryBarrier_linux.cpp | 10 +++---- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 92996789394..57b8a37baf2 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -378,9 +378,10 @@ 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::kernel_version(long* major, long* minor, long* patch) { + *major = 0; + *minor = 0; + *patch = 0; struct utsname buffer; int ret = uname(&buffer); @@ -388,12 +389,29 @@ void os::Linux::kernel_version(long* major, long* minor) { log_warning(os)("uname(2) failed to get kernel version: %s", os::errno_name(ret)); return; } - int nr_matched = sscanf(buffer.release, "%ld.%ld", major, minor); - if (nr_matched != 2) { - log_warning(os)("Parsing kernel version failed, expected 2 version numbers, only matched %d", nr_matched); + int nr_matched = sscanf(buffer.release, "%ld.%ld.%ld", major, minor, patch); + if (nr_matched != 3) { + log_warning(os)("Parsing kernel version failed, expected 3 version numbers, only matched %d", nr_matched); } } +int os::Linux::kernel_version_compare(long major1, long minor1, long patch1, + long major2, long minor2, long patch2) { + // Compare major versions + if (major1 > major2) return 1; + if (major1 < major2) return -1; + + // Compare minor versions + if (minor1 > minor2) return 1; + if (minor1 < minor2) return -1; + + // Compare patchlevel versions + if (patch1 > patch2) return 1; + if (patch1 < patch2) return -1; + + return 0; +} + bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu) { FILE* fh; uint64_t userTicks, niceTicks, systemTicks, idleTicks; diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 29848580c4a..bd2e1ea3230 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -91,7 +91,13 @@ class os::Linux { }; static int active_processor_count(); - static void kernel_version(long* major, long* minor); + static void kernel_version(long* major, long* minor, long* patch); + + // If kernel1 > kernel2 return 1 + // If kernel1 < kernel2 return -1 + // If kernel1 = kernel2 return 0 + static int kernel_version_compare(long major1, long minor1, long patch1, + long major2, long minor2, long patch2); // which_logical_cpu=-1 returns accumulated ticks for all cpus. static bool get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu); diff --git a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp index 870b3f5016a..766bb70a977 100644 --- a/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp +++ b/src/hotspot/os/linux/systemMemoryBarrier_linux.cpp @@ -66,11 +66,11 @@ bool LinuxSystemMemoryBarrier::initialize() { // RISCV port was introduced in kernel 4.4. // 4.4 also made membar private expedited mandatory. // But RISCV actually don't support it until 6.9. - long major, minor; - os::Linux::kernel_version(&major, &minor); - if (!(major > 6 || (major == 6 && minor >= 9))) { - log_info(os)("Linux kernel %ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.", - major, minor); + long major, minor, patch; + os::Linux::kernel_version(&major, &minor, &patch); + if (os::Linux::kernel_version_compare(major, minor, patch, 6, 9, 0) == -1) { + log_info(os)("Linux kernel %ld.%ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.", + major, minor, patch); return false; } #endif