8266349: Pass down requested page size to reserve_memory_special

Reviewed-by: stuefe, mgkwill
This commit is contained in:
Stefan Johansson 2021-05-07 11:33:10 +00:00
parent e0c86884e5
commit 2798b0d98a
10 changed files with 38 additions and 34 deletions

View file

@ -2141,7 +2141,7 @@ void os::large_page_init() {
return; // Nothing to do. See query_multipage_support and friends.
}
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {
fatal("os::reserve_memory_special should not be called on AIX.");
return NULL;
}

View file

@ -1776,7 +1776,7 @@ void os::large_page_init() {
}
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {
fatal("os::reserve_memory_special should not be called on BSD.");
return NULL;
}

View file

@ -3957,14 +3957,15 @@ bool os::Linux::commit_memory_special(size_t bytes,
char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes,
size_t alignment,
size_t page_size,
char* req_addr,
bool exec) {
assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
assert(is_aligned(req_addr, alignment), "Must be");
assert(is_aligned(req_addr, os::large_page_size()), "Must be");
assert(is_aligned(req_addr, page_size), "Must be");
assert(is_aligned(alignment, os::vm_allocation_granularity()), "Must be");
assert(is_power_of_2(os::large_page_size()), "Must be");
assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes");
assert(_page_sizes.contains(page_size), "Must be a valid page size");
assert(bytes >= page_size, "Shouldn't allocate large pages for small sizes");
// We only end up here when at least 1 large page can be used.
// If the size is not a multiple of the large page size, we
@ -3974,15 +3975,15 @@ char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes,
// a requested address is given it will be used and it must be
// aligned to both the large page size and the given alignment.
// The larger of the two will be used.
size_t required_alignment = MAX(os::large_page_size(), alignment);
size_t required_alignment = MAX(page_size, alignment);
char* const aligned_start = anon_mmap_aligned(req_addr, bytes, required_alignment);
if (aligned_start == NULL) {
return NULL;
}
// First commit using large pages.
size_t large_bytes = align_down(bytes, os::large_page_size());
bool large_committed = commit_memory_special(large_bytes, os::large_page_size(), aligned_start, exec);
size_t large_bytes = align_down(bytes, page_size);
bool large_committed = commit_memory_special(large_bytes, page_size, aligned_start, exec);
if (large_committed && bytes == large_bytes) {
// The size was large page aligned so no additional work is
@ -4011,16 +4012,17 @@ char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes,
return aligned_start;
}
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment,
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size,
char* req_addr, bool exec) {
assert(UseLargePages, "only for large pages");
char* addr;
if (UseSHM) {
// No support for using specific page sizes with SHM.
addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
} else {
assert(UseHugeTLBFS, "must be");
addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec);
addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, page_size, req_addr, exec);
}
if (addr != NULL) {

View file

@ -90,7 +90,7 @@ class Linux {
static int hugetlbfs_page_size_flag(size_t page_size);
static char* reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec);
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec);
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec);
static bool commit_memory_special(size_t bytes, size_t page_size, char* req_addr, bool exec);
static bool release_memory_special_impl(char* base, size_t bytes);

View file

@ -3274,11 +3274,12 @@ bool os::can_execute_large_page_memory() {
return true;
}
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, char* addr,
char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* addr,
bool exec) {
assert(UseLargePages, "only for large pages");
assert(page_size == os::large_page_size(), "Currently only support one large page size on Windows");
if (!is_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
if (!is_aligned(bytes, page_size) || alignment > page_size) {
return NULL; // Fallback to small pages.
}

View file

@ -169,14 +169,14 @@ static char* reserve_memory(char* requested_address, const size_t size,
}
static char* reserve_memory_special(char* requested_address, const size_t size,
const size_t alignment, bool exec) {
const size_t alignment, const size_t page_size, bool exec) {
log_trace(pagesize)("Attempt special mapping: size: " SIZE_FORMAT "%s, "
"alignment: " SIZE_FORMAT "%s",
byte_size_in_exact_unit(size), exact_unit_for_byte_size(size),
byte_size_in_exact_unit(alignment), exact_unit_for_byte_size(alignment));
char* base = os::reserve_memory_special(size, alignment, requested_address, exec);
char* base = os::reserve_memory_special(size, alignment, page_size, requested_address, exec);
if (base != NULL) {
// Check alignment constraints.
assert(is_aligned(base, alignment),
@ -236,7 +236,7 @@ void ReservedSpace::reserve(size_t size,
// explicit large pages and these have to be committed up front to ensure
// no reservations are lost.
char* base = reserve_memory_special(requested_address, size, alignment, executable);
char* base = reserve_memory_special(requested_address, size, alignment, page_size, executable);
if (base != NULL) {
// Successful reservation using large pages.
initialize_members(base, size, alignment, page_size, true, executable);

View file

@ -1890,12 +1890,12 @@ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
pd_realign_memory(addr, bytes, alignment_hint);
}
char* os::reserve_memory_special(size_t size, size_t alignment,
char* os::reserve_memory_special(size_t size, size_t alignment, size_t page_size,
char* addr, bool executable) {
assert(is_aligned(addr, alignment), "Unaligned request address");
char* result = pd_reserve_memory_special(size, alignment, addr, executable);
char* result = pd_reserve_memory_special(size, alignment, page_size, addr, executable);
if (result != NULL) {
// The memory is committed
MemTracker::record_virtual_memory_reserve_and_commit((address)result, size, CALLER_PC);

View file

@ -159,7 +159,8 @@ class os: AllStatic {
static void pd_free_memory(char *addr, size_t bytes, size_t alignment_hint);
static void pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint);
static char* pd_reserve_memory_special(size_t size, size_t alignment,
static char* pd_reserve_memory_special(size_t size, size_t alignment, size_t page_size,
char* addr, bool executable);
static bool pd_release_memory_special(char* addr, size_t bytes);
@ -428,7 +429,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,
static char* reserve_memory_special(size_t size, size_t alignment, size_t page_size,
char* addr, bool executable);
static bool release_memory_special(char* addr, size_t bytes);
static void large_page_init();

View file

@ -47,8 +47,8 @@ namespace {
char* const _ptr;
const size_t _size;
public:
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec) {
return os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec);
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {
return os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, page_size, req_addr, exec);
}
HugeTlbfsMemory(char* const ptr, size_t size) : _ptr(ptr), _size(size) { }
~HugeTlbfsMemory() {
@ -100,7 +100,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_aligned) {
size_t lp = os::large_page_size();
for (size_t size = lp; size <= lp * 10; size += lp) {
char* addr = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, lp, NULL, false);
char* addr = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, lp, lp, NULL, false);
if (addr != NULL) {
HugeTlbfsMemory mr(addr, size);
@ -126,7 +126,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_without_add
for (int i = 0; i < num_sizes; i++) {
const size_t size = sizes[i];
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
char* p = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, alignment, NULL, false);
char* p = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, alignment, lp, NULL, false);
if (p != NULL) {
HugeTlbfsMemory mr(p, size);
EXPECT_PRED2(is_ptr_aligned, p, alignment) << " size = " << size;
@ -166,7 +166,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_with_good_r
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
// req_addr must be at least large page aligned.
char* const req_addr = align_up(mapping, MAX2(alignment, lp));
char* p = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, alignment, req_addr, false);
char* p = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, alignment, lp, req_addr, false);
if (p != NULL) {
HugeTlbfsMemory mr(p, size);
ASSERT_EQ(req_addr, p) << " size = " << size << ", alignment = " << alignment;
@ -216,7 +216,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_with_bad_re
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
// req_addr must be at least large page aligned.
char* const req_addr = align_up(mapping, MAX2(alignment, lp));
char* p = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, alignment, req_addr, false);
char* p = HugeTlbfsMemory::reserve_memory_special_huge_tlbfs(size, alignment, lp, req_addr, false);
HugeTlbfsMemory mr(p, size);
// as the area around req_addr contains already existing mappings, the API should always
// return NULL (as per contract, it cannot return another address)
@ -253,12 +253,12 @@ class TestReserveMemorySpecial : AllStatic {
}
}
static void test_reserve_memory_special_huge_tlbfs_size_aligned(size_t size, size_t alignment) {
static void test_reserve_memory_special_huge_tlbfs_size_aligned(size_t size, size_t alignment, size_t page_size) {
if (!UseHugeTLBFS) {
return;
}
char* addr = os::Linux::reserve_memory_special_huge_tlbfs(size, alignment, NULL, false);
char* addr = os::Linux::reserve_memory_special_huge_tlbfs(size, alignment, page_size, NULL, false);
if (addr != NULL) {
small_page_write(addr, size);
@ -275,7 +275,7 @@ class TestReserveMemorySpecial : AllStatic {
size_t lp = os::large_page_size();
for (size_t size = lp; size <= lp * 10; size += lp) {
test_reserve_memory_special_huge_tlbfs_size_aligned(size, lp);
test_reserve_memory_special_huge_tlbfs_size_aligned(size, lp, lp);
}
}
@ -319,7 +319,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::Linux::reserve_memory_special_huge_tlbfs(size, alignment, NULL, false);
char* p = os::Linux::reserve_memory_special_huge_tlbfs(size, alignment, lp, NULL, false);
if (p != NULL) {
EXPECT_TRUE(is_aligned(p, alignment));
small_page_write(p, size);
@ -334,7 +334,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::Linux::reserve_memory_special_huge_tlbfs(size, alignment, req_addr, false);
char* p = os::Linux::reserve_memory_special_huge_tlbfs(size, alignment, lp, req_addr, false);
if (p != NULL) {
EXPECT_EQ(p, req_addr);
small_page_write(p, size);
@ -349,7 +349,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::Linux::reserve_memory_special_huge_tlbfs(size, alignment, req_addr, false);
char* p = os::Linux::reserve_memory_special_huge_tlbfs(size, alignment, lp, req_addr, false);
// as the area around req_addr contains already existing mappings, the API should always
// return NULL (as per contract, it cannot return another address)
EXPECT_TRUE(p == NULL);

View file

@ -64,7 +64,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(), NULL, false);
char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), os::large_page_size(), NULL, false);
if (result != NULL) {
// failed to allocate memory, skipping the test
return;
@ -75,7 +75,7 @@ void TestReserveMemorySpecial_test() {
// we managed to get it once.
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(), expected_location, false);
char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), os::large_page_size(), expected_location, false);
if (actual_location != NULL) {
// failed to allocate memory, skipping the test
return;