8271195: Use largest available large page size smaller than LargePageSizeInBytes when available
Co-authored-by: Jatin Bhateja <jbhateja@openjdk.org> Reviewed-by: ayang, tschatzl
This commit is contained in:
parent
de4f04cb71
commit
08cadb4754
src/hotspot
test/micro/org/openjdk/bench/vm/gc
@ -3972,23 +3972,14 @@ char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment,
|
||||
return addr;
|
||||
}
|
||||
|
||||
static void warn_on_commit_special_failure(char* req_addr, size_t bytes,
|
||||
static void log_on_commit_special_failure(char* req_addr, size_t bytes,
|
||||
size_t page_size, int error) {
|
||||
assert(error == ENOMEM, "Only expect to fail if no memory is available");
|
||||
|
||||
bool warn_on_failure = UseLargePages &&
|
||||
(!FLAG_IS_DEFAULT(UseLargePages) ||
|
||||
!FLAG_IS_DEFAULT(UseHugeTLBFS) ||
|
||||
!FLAG_IS_DEFAULT(LargePageSizeInBytes));
|
||||
|
||||
if (warn_on_failure) {
|
||||
char msg[128];
|
||||
jio_snprintf(msg, sizeof(msg), "Failed to reserve and commit memory. req_addr: "
|
||||
PTR_FORMAT " bytes: " SIZE_FORMAT " page size: "
|
||||
SIZE_FORMAT " (errno = %d).",
|
||||
req_addr, bytes, page_size, error);
|
||||
warning("%s", msg);
|
||||
}
|
||||
log_info(pagesize)("Failed to reserve and commit memory with given page size. req_addr: " PTR_FORMAT
|
||||
" size: " SIZE_FORMAT "%s, page size: " SIZE_FORMAT "%s, (errno = %d)",
|
||||
p2i(req_addr), byte_size_in_exact_unit(bytes), exact_unit_for_byte_size(bytes),
|
||||
byte_size_in_exact_unit(page_size), exact_unit_for_byte_size(page_size), error);
|
||||
}
|
||||
|
||||
bool os::Linux::commit_memory_special(size_t bytes,
|
||||
@ -4010,7 +4001,7 @@ bool os::Linux::commit_memory_special(size_t bytes,
|
||||
char* addr = (char*)::mmap(req_addr, bytes, prot, flags, -1, 0);
|
||||
|
||||
if (addr == MAP_FAILED) {
|
||||
warn_on_commit_special_failure(req_addr, bytes, page_size, errno);
|
||||
log_on_commit_special_failure(req_addr, bytes, page_size, errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,19 @@ static bool large_pages_requested() {
|
||||
(!FLAG_IS_DEFAULT(UseLargePages) || !FLAG_IS_DEFAULT(LargePageSizeInBytes));
|
||||
}
|
||||
|
||||
static void log_on_large_pages_failure(char* req_addr, size_t bytes) {
|
||||
if (large_pages_requested()) {
|
||||
// Compressed oops logging.
|
||||
log_debug(gc, heap, coops)("Reserve regular memory without large pages");
|
||||
// JVM style warning that we did not succeed in using large pages.
|
||||
char msg[128];
|
||||
jio_snprintf(msg, sizeof(msg), "Failed to reserve and commit memory using large pages. "
|
||||
"req_addr: " PTR_FORMAT " bytes: " SIZE_FORMAT,
|
||||
req_addr, bytes);
|
||||
warning("%s", msg);
|
||||
}
|
||||
}
|
||||
|
||||
static char* reserve_memory(char* requested_address, const size_t size,
|
||||
const size_t alignment, int fd, bool exec) {
|
||||
char* base;
|
||||
@ -183,10 +196,6 @@ static char* reserve_memory_special(char* requested_address, const size_t size,
|
||||
"reserve_memory_special() returned an unaligned address, base: " PTR_FORMAT
|
||||
" alignment: " SIZE_FORMAT_HEX,
|
||||
p2i(base), alignment);
|
||||
} else {
|
||||
if (large_pages_requested()) {
|
||||
log_debug(gc, heap, coops)("Reserve regular memory without large pages");
|
||||
}
|
||||
}
|
||||
return base;
|
||||
}
|
||||
@ -235,14 +244,25 @@ void ReservedSpace::reserve(size_t size,
|
||||
// the caller requested large pages. To satisfy this request we use
|
||||
// explicit large pages and these have to be committed up front to ensure
|
||||
// no reservations are lost.
|
||||
size_t used_page_size = page_size;
|
||||
char* base = NULL;
|
||||
|
||||
do {
|
||||
base = reserve_memory_special(requested_address, size, alignment, used_page_size, executable);
|
||||
if (base != NULL) {
|
||||
break;
|
||||
}
|
||||
used_page_size = os::page_sizes().next_smaller(used_page_size);
|
||||
} while (used_page_size > (size_t) os::vm_page_size());
|
||||
|
||||
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);
|
||||
initialize_members(base, size, alignment, used_page_size, true, executable);
|
||||
return;
|
||||
}
|
||||
// Failed to reserve explicit large pages, fall back to normal reservation.
|
||||
// Failed to reserve explicit large pages, do proper logging.
|
||||
log_on_large_pages_failure(requested_address, size);
|
||||
// Now fall back to normal reservation.
|
||||
page_size = os::vm_page_size();
|
||||
}
|
||||
|
||||
|
62
test/micro/org/openjdk/bench/vm/gc/MicroLargePages.java
Normal file
62
test/micro/org/openjdk/bench/vm/gc/MicroLargePages.java
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Copyright (c) 2022, 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
|
||||
// under the terms of the GNU General Public License version 2 only, as
|
||||
// published by the Free Software Foundation.
|
||||
//
|
||||
// This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// version 2 for more details (a copy is included in the LICENSE file that
|
||||
// accompanied this code).
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License version
|
||||
// 2 along with this work; if not, write to the Free Software Foundation,
|
||||
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
// or visit www.oracle.com if you need additional information or have any
|
||||
// questions.
|
||||
//
|
||||
|
||||
package org.openjdk.bench.vm.gc;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
@OutputTimeUnit(TimeUnit.MINUTES)
|
||||
@State(Scope.Thread)
|
||||
@Fork(jvmArgsAppend = {"-Xmx256m", "-XX:+UseLargePages", "-XX:LargePageSizeInBytes=1g", "-Xlog:pagesize"}, value = 5)
|
||||
|
||||
public class MicroLargePages {
|
||||
|
||||
@Param({"2097152"})
|
||||
public int ARRAYSIZE;
|
||||
|
||||
@Param({"1", "2", "4"})
|
||||
public int NUM;
|
||||
|
||||
public long[][] INP;
|
||||
public long[][] OUT;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void BmSetup() {
|
||||
INP = new long[NUM][ARRAYSIZE];
|
||||
OUT = new long[NUM][ARRAYSIZE];
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
Arrays.fill(INP[i], 10);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void micro_HOP_DIST_4KB() {
|
||||
for (int i = 0; i < NUM; i += 1) {
|
||||
for (int j = 0; j < ARRAYSIZE; j += 512) {
|
||||
OUT[i][j] = INP[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user