8324580: SIGFPE on THP initialization on kernels < 4.10

Reviewed-by: stuefe, sjohanss
This commit is contained in:
Zdenek Zambersky 2024-02-15 16:01:18 +00:00 committed by Thomas Stuefe
parent 2564f0f998
commit a231706a06
5 changed files with 35 additions and 2 deletions

@ -311,6 +311,19 @@ ExplicitHugePageSupport HugePages::_explicit_hugepage_support;
THPSupport HugePages::_thp_support;
ShmemTHPSupport HugePages::_shmem_thp_support;
size_t HugePages::thp_pagesize_fallback() {
// Older kernels won't publish the THP page size. Fall back to default static huge page size,
// since that is likely to be the THP page size as well. Don't do it if the page size is considered
// too large to avoid large alignment waste. If static huge page size is unknown, use educated guess.
if (thp_pagesize() != 0) {
return thp_pagesize();
}
if (supports_static_hugepages()) {
return MIN2(default_static_hugepage_size(), 16 * M);
}
return 2 * M;
}
void HugePages::initialize() {
_explicit_hugepage_support.scan_os();
_thp_support.scan_os();

@ -138,6 +138,7 @@ public:
static bool supports_thp() { return thp_mode() == THPMode::madvise || thp_mode() == THPMode::always; }
static THPMode thp_mode() { return _thp_support.mode(); }
static size_t thp_pagesize() { return _thp_support.pagesize(); }
static size_t thp_pagesize_fallback();
static bool supports_shmem_thp() { return _shmem_thp_support.is_enabled(); }
static ShmemTHPMode shmem_thp_mode() { return _shmem_thp_support.mode(); }

@ -3935,8 +3935,12 @@ void os::Linux::large_page_init() {
// In THP mode:
// - os::large_page_size() is the *THP page size*
// - os::pagesizes() has two members, the THP page size and the system page size
assert(HugePages::thp_pagesize() > 0, "Missing OS info");
_large_page_size = HugePages::thp_pagesize();
if (_large_page_size == 0) {
log_info(pagesize) ("Cannot determine THP page size (kernel < 4.10 ?)");
_large_page_size = HugePages::thp_pagesize_fallback();
log_info(pagesize) ("Assuming THP page size to be: " EXACTFMT " (heuristics)", EXACTFMTARGS(_large_page_size));
}
_page_sizes.add(_large_page_size);
_page_sizes.add(os::vm_page_size());
// +UseTransparentHugePages implies +UseLargePages

@ -86,6 +86,20 @@ class HugePageConfiguration {
return _thpPageSize;
}
// Returns the THP page size (if exposed by the kernel) or a guessed THP page size.
// Mimics HugePages::thp_pagesize_fallback() method in hotspot (must be kept in sync with it).
public long getThpPageSizeOrFallback() {
long pageSize = getThpPageSize();
if (pageSize != 0) {
return pageSize;
}
pageSize = getStaticDefaultHugePageSize();
if (pageSize != 0) {
return Math.min(pageSize, 16 * 1024 * 1024);
}
return 2 * 1024 * 1024;
}
// Returns true if the THP support is enabled
public boolean supportsTHP() {
return _thpMode == THPMode.always || _thpMode == THPMode.madvise;

@ -125,7 +125,8 @@ public class TestHugePageDecisionsAtVMStartup {
out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=0");
out.shouldContain("[info][pagesize] Large page support enabled");
} else if (useLP && useTHP && configuration.supportsTHP()) {
String thpPageSizeString = buildSizeString(configuration.getThpPageSize());
long thpPageSize = configuration.getThpPageSizeOrFallback();
String thpPageSizeString = buildSizeString(thpPageSize);
// We expect to see exactly two "Usable page sizes" : the system page size and the THP page size. The system
// page size differs, but its always in KB).
out.shouldContain("[info][pagesize] UseLargePages=1, UseTransparentHugePages=1");