8386476: NMT: Large page reservation not attributed to the correct memory tag

Reviewed-by: jsjolen, stefank, tschatzl
This commit is contained in:
Albert Mingkun Yang 2026-06-12 15:08:53 +00:00
parent d3d67ece7c
commit 41d5a1bdcd
7 changed files with 20 additions and 18 deletions

View File

@ -125,12 +125,13 @@ ReservedSpace MemoryReserver::reserve_memory_special(char* requested_address,
size_t size,
size_t alignment,
size_t page_size,
bool exec) {
bool exec,
MemTag mem_tag) {
log_trace(pagesize)("Attempt special mapping: size: " EXACTFMT ", alignment: " EXACTFMT,
EXACTFMTARGS(size),
EXACTFMTARGS(alignment));
char* base = os::reserve_memory_special(size, alignment, page_size, requested_address, exec);
char* base = os::reserve_memory_special(size, alignment, page_size, requested_address, mem_tag, exec);
if (base != nullptr) {
assert(is_aligned(base, alignment),
@ -172,7 +173,7 @@ ReservedSpace MemoryReserver::reserve(char* requested_address,
// explicit large pages and these have to be committed up front to ensure
// no reservations are lost.
do {
ReservedSpace reserved = reserve_memory_special(requested_address, size, alignment, page_size, executable);
ReservedSpace reserved = reserve_memory_special(requested_address, size, alignment, page_size, executable, mem_tag);
if (reserved.is_reserved()) {
// Successful reservation using large pages.
return reserved;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,8 @@ class MemoryReserver : AllStatic {
size_t size,
size_t alignment,
size_t page_size,
bool exec);
bool exec,
MemTag mem_tag);
public:
// Final destination

View File

@ -2397,14 +2397,14 @@ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
}
char* os::reserve_memory_special(size_t size, size_t alignment, size_t page_size,
char* addr, bool executable) {
char* addr, MemTag mem_tag, bool executable) {
assert(is_aligned(addr, alignment), "Unaligned request address");
char* result = pd_reserve_memory_special(size, alignment, page_size, addr, executable);
if (result != nullptr) {
// The memory is committed
MemTracker::record_virtual_memory_reserve_and_commit((address)result, size, CALLER_PC, mtNone);
MemTracker::record_virtual_memory_reserve_and_commit((address)result, size, CALLER_PC, mem_tag);
log_debug(os, map)("Reserved and committed " RANGEFMT, RANGEFMTARGS(result, size));
} else {
log_info(os, map)("Reserve and commit failed (%zu bytes)", size);

View File

@ -601,7 +601,7 @@ class os: AllStatic {
static char* non_memory_address_word();
// reserve, commit and pin the entire memory region
static char* reserve_memory_special(size_t size, size_t alignment, size_t page_size,
char* addr, bool executable);
char* addr, MemTag mem_tag, bool executable);
static void large_page_init();
static size_t large_page_size();
static bool can_commit_large_page_memory();

View File

@ -1105,7 +1105,7 @@ TEST_VM(os, reserve_at_wish_address_shall_not_replace_mappings_largepages) {
const size_t lpsz = os::large_page_size();
char* p1 = os::reserve_memory_aligned(lpsz, lpsz, mtTest);
ASSERT_NE(p1, nullptr);
char* p2 = os::reserve_memory_special(lpsz, lpsz, lpsz, p1, false);
char* p2 = os::reserve_memory_special(lpsz, lpsz, lpsz, p1, mtTest, false);
ASSERT_EQ(p2, nullptr); // should have failed
os::release_memory(p1, M);
} else {

View File

@ -54,7 +54,7 @@ namespace {
const size_t _size;
public:
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {
return os::reserve_memory_special(bytes, alignment, page_size, req_addr, exec);
return os::reserve_memory_special(bytes, alignment, page_size, req_addr, mtTest, exec);
}
HugeTlbfsMemory(char* const ptr, size_t size) : _ptr(ptr), _size(size) { }
~HugeTlbfsMemory() {
@ -224,7 +224,7 @@ class TestReserveMemorySpecial : AllStatic {
if (!using_explicit_hugepages()) {
return;
}
char* addr = os::reserve_memory_special(size, alignment, page_size, nullptr, false);
char* addr = os::reserve_memory_special(size, alignment, page_size, nullptr, mtTest, false);
if (addr != nullptr) {
small_page_write(addr, size);
os::release_memory(addr, size);
@ -281,7 +281,7 @@ class TestReserveMemorySpecial : AllStatic {
for (int i = 0; i < num_sizes; i++) {
const size_t size = sizes[i];
for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
char* p = os::reserve_memory_special(size, alignment, lp, nullptr, false);
char* p = os::reserve_memory_special(size, alignment, lp, nullptr, mtTest, false);
if (p != nullptr) {
EXPECT_TRUE(is_aligned(p, alignment));
small_page_write(p, size);
@ -296,7 +296,7 @@ class TestReserveMemorySpecial : AllStatic {
for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
// req_addr must be at least large page aligned.
char* const req_addr = align_up(mapping1, MAX2(alignment, lp));
char* p = os::reserve_memory_special(size, alignment, lp, req_addr, false);
char* p = os::reserve_memory_special(size, alignment, lp, req_addr, mtTest, false);
if (p != nullptr) {
EXPECT_EQ(p, req_addr);
small_page_write(p, size);
@ -311,7 +311,7 @@ class TestReserveMemorySpecial : AllStatic {
for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
// req_addr must be at least large page aligned.
char* const req_addr = align_up(mapping2, MAX2(alignment, lp));
char* p = os::reserve_memory_special(size, alignment, lp, req_addr, false);
char* p = os::reserve_memory_special(size, alignment, lp, req_addr, mtTest, false);
// as the area around req_addr contains already existing mappings, the API should always
// return nullptr (as per contract, it cannot return another address)
EXPECT_TRUE(p == nullptr);

View File

@ -67,7 +67,7 @@ void TestReserveMemorySpecial_test() {
FLAG_SET_CMDLINE(UseNUMAInterleaving, false);
const size_t large_allocation_size = os::large_page_size() * 4;
char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), os::large_page_size(), nullptr, false);
char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), os::large_page_size(), nullptr, mtTest, false);
if (result == nullptr) {
// failed to allocate memory, skipping the test
return;
@ -77,12 +77,12 @@ void TestReserveMemorySpecial_test() {
// Reserve another page within the recently allocated memory area. This should fail
const size_t expected_allocation_size = os::large_page_size();
char* expected_location = result + os::large_page_size();
char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), os::large_page_size(), expected_location, false);
char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), os::large_page_size(), expected_location, mtTest, false);
EXPECT_TRUE(actual_location == nullptr) << "Should not be allowed to reserve within present reservation";
// Instead try reserving after the first reservation.
expected_location = result + large_allocation_size;
actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), os::large_page_size(), expected_location, false);
actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), os::large_page_size(), expected_location, mtTest, false);
EXPECT_TRUE(actual_location != nullptr) << "Unexpected reservation failure, can't verify correct location";
EXPECT_TRUE(actual_location == expected_location) << "Reservation must be at requested location";
MemoryReleaser m2(actual_location, os::large_page_size());
@ -90,7 +90,7 @@ void TestReserveMemorySpecial_test() {
// Now try to do a reservation with a larger alignment.
const size_t alignment = os::large_page_size() * 2;
const size_t new_large_size = alignment * 4;
char* aligned_request = os::reserve_memory_special(new_large_size, alignment, os::large_page_size(), nullptr, false);
char* aligned_request = os::reserve_memory_special(new_large_size, alignment, os::large_page_size(), nullptr, mtTest, false);
EXPECT_TRUE(aligned_request != nullptr) << "Unexpected reservation failure, can't verify correct alignment";
EXPECT_TRUE(is_aligned(aligned_request, alignment)) << "Returned address must be aligned";
MemoryReleaser m3(aligned_request, new_large_size);