diff --git a/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java b/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java index 2def134b9d3..7c0dfb2f3bb 100644 --- a/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java +++ b/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -56,6 +56,7 @@ import jdk.test.lib.os.linux.HugePageConfiguration; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; +import jtreg.SkippedException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -123,6 +124,9 @@ public class TestHugePageDecisionsAtVMStartup { out.shouldContain(warningNoTHP); } else if (useLP && !useTHP && configuration.supportsExplicitHugePages() && haveUsableExplicitHugePages) { + if (configuration.getExplicitAvailableHugePageNumber() == 0) { + throw new SkippedException("No usable explicit hugepages configured on the system, skipping test"); + } out.shouldContain("[info][pagesize] Using the default large page size: " + buildSizeString(configuration.getExplicitDefaultHugePageSize())); out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=0"); out.shouldContain("[info][pagesize] Large page support enabled"); diff --git a/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java b/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java index 0873cb2b5d0..d95f20d27fd 100644 --- a/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java +++ b/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java @@ -64,6 +64,7 @@ public class HugePageConfiguration { Set _explicitHugePageConfigurations; long _explicitDefaultHugePageSize = -1; + long _explicitAvailableHugePageNumber = -1; public enum THPMode {always, never, madvise} THPMode _thpMode; @@ -80,6 +81,10 @@ public class HugePageConfiguration { return _explicitDefaultHugePageSize; } + public long getExplicitAvailableHugePageNumber() { + return _explicitAvailableHugePageNumber; + } + public THPMode getThpMode() { return _thpMode; } @@ -116,9 +121,10 @@ public class HugePageConfiguration { return _explicitDefaultHugePageSize > 0 && _explicitHugePageConfigurations.size() > 0; } - public HugePageConfiguration(Set explicitHugePageConfigurations, long explicitDefaultHugePageSize, THPMode _thpMode, long _thpPageSize, ShmemTHPMode _shmemThpMode) { + public HugePageConfiguration(Set explicitHugePageConfigurations, long explicitDefaultHugePageSize, long explicitAvailableHugePageNumber, THPMode _thpMode, long _thpPageSize, ShmemTHPMode _shmemThpMode) { this._explicitHugePageConfigurations = explicitHugePageConfigurations; this._explicitDefaultHugePageSize = explicitDefaultHugePageSize; + this._explicitAvailableHugePageNumber = explicitAvailableHugePageNumber; this._thpMode = _thpMode; this._thpPageSize = _thpPageSize; this._shmemThpMode = _shmemThpMode; @@ -129,6 +135,7 @@ public class HugePageConfiguration { return "Configuration{" + "_explicitHugePageConfigurations=" + _explicitHugePageConfigurations + ", _explicitDefaultHugePageSize=" + _explicitDefaultHugePageSize + + ", _explicitAvailableHugePageNumber=" + _explicitAvailableHugePageNumber + ", _thpMode=" + _thpMode + ", _thpPageSize=" + _thpPageSize + ", _shmemThpMode=" + _shmemThpMode + @@ -138,6 +145,7 @@ public class HugePageConfiguration { @Override public int hashCode() { return Objects.hash(_explicitDefaultHugePageSize, + _explicitAvailableHugePageNumber, _thpPageSize, _explicitHugePageConfigurations, _thpMode, @@ -149,6 +157,7 @@ public class HugePageConfiguration { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; HugePageConfiguration that = (HugePageConfiguration) o; + // _explicitAvailableHugePageNumber is not compared here, because there is no direct counterpart on the JVM-side log. return _explicitDefaultHugePageSize == that._explicitDefaultHugePageSize && _thpPageSize == that._thpPageSize && Objects.equals(_explicitHugePageConfigurations, that._explicitHugePageConfigurations) && _thpMode == that._thpMode && _shmemThpMode == that._shmemThpMode; @@ -169,6 +178,21 @@ public class HugePageConfiguration { return 0; } + private static long readAvailableHugePageNumberFromOS() { + Pattern pat = Pattern.compile("HugePages_Free: *(\\d+)$"); + try (Scanner scanner = new Scanner(new File("/proc/meminfo"))) { + while (scanner.hasNextLine()) { + Matcher mat = pat.matcher(scanner.nextLine()); + if (mat.matches()) { + return Long.parseLong(mat.group(1)); + } + } + } catch (FileNotFoundException e) { + System.out.println("Could not open /proc/meminfo"); + } + return 0; + } + private static Set readSupportedHugePagesFromOS() throws IOException { TreeSet hugePageConfigs = new TreeSet<>(); Pattern pat = Pattern.compile("hugepages-(\\d+)kB"); @@ -263,6 +287,7 @@ public class HugePageConfiguration { public static HugePageConfiguration readFromOS() throws IOException { return new HugePageConfiguration(readSupportedHugePagesFromOS(), readDefaultHugePageSizeFromOS(), + readAvailableHugePageNumberFromOS(), readTHPModeFromOS(), readTHPPageSizeFromOS(), readShmemTHPModeFromOS()); @@ -333,7 +358,7 @@ public class HugePageConfiguration { } } - return new HugePageConfiguration(explicitHugePageConfigs, defaultHugepageSize, thpMode, thpPageSize, shmemThpMode); + return new HugePageConfiguration(explicitHugePageConfigs, defaultHugepageSize, -1, thpMode, thpPageSize, shmemThpMode); } }