8261894: Remove support for UseSHM
Reviewed-by: dholmes, ayang
This commit is contained in:
parent
ad7a8e86e0
commit
c2abf120bc
@ -44,18 +44,12 @@
|
||||
product(bool, UseLinuxPosixThreadCPUClocks, true, \
|
||||
"enable fast Linux Posix clocks where available") \
|
||||
\
|
||||
product(bool, UseHugeTLBFS, false, \
|
||||
"Use MAP_HUGETLB for large pages") \
|
||||
\
|
||||
product(bool, UseTransparentHugePages, false, \
|
||||
"Use MADV_HUGEPAGE for large pages") \
|
||||
\
|
||||
product(bool, LoadExecStackDllInVMThread, true, \
|
||||
"Load DLLs with executable-stack attribute in the VM Thread") \
|
||||
\
|
||||
product(bool, UseSHM, false, \
|
||||
"Use SYSV shared memory for large pages") \
|
||||
\
|
||||
product(bool, UseContainerSupport, true, \
|
||||
"Enable detection and runtime container configuration support") \
|
||||
\
|
||||
|
@ -111,7 +111,6 @@
|
||||
# include <syscall.h>
|
||||
# include <sys/sysinfo.h>
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/shm.h>
|
||||
# include <link.h>
|
||||
# include <stdint.h>
|
||||
# include <inttypes.h>
|
||||
@ -3607,14 +3606,17 @@ bool os::unguard_memory(char* addr, size_t size) {
|
||||
return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
|
||||
}
|
||||
|
||||
int os::Linux::hugetlbfs_page_size_flag(size_t page_size) {
|
||||
static int hugetlbfs_page_size_flag(size_t page_size) {
|
||||
if (page_size != HugePages::default_static_hugepage_size()) {
|
||||
return (exact_log2(page_size) << MAP_HUGE_SHIFT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
static bool hugetlbfs_sanity_check(size_t page_size) {
|
||||
const os::PageSizes page_sizes = HugePages::static_info().pagesizes();
|
||||
assert(page_sizes.contains(page_size), "Invalid page sizes passed");
|
||||
|
||||
// Include the page size flag to ensure we sanity check the correct page size.
|
||||
int flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB | hugetlbfs_page_size_flag(page_size);
|
||||
void *p = mmap(nullptr, page_size, PROT_READ|PROT_WRITE, flags, -1, 0);
|
||||
@ -3628,9 +3630,9 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
"checking if smaller large page sizes are usable",
|
||||
byte_size_in_exact_unit(page_size),
|
||||
exact_unit_for_byte_size(page_size));
|
||||
for (size_t page_size_ = _page_sizes.next_smaller(page_size);
|
||||
page_size_ != os::vm_page_size();
|
||||
page_size_ = _page_sizes.next_smaller(page_size_)) {
|
||||
for (size_t page_size_ = page_sizes.next_smaller(page_size);
|
||||
page_size_ > os::vm_page_size();
|
||||
page_size_ = page_sizes.next_smaller(page_size_)) {
|
||||
flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB | hugetlbfs_page_size_flag(page_size_);
|
||||
p = mmap(nullptr, page_size_, PROT_READ|PROT_WRITE, flags, -1, 0);
|
||||
if (p != MAP_FAILED) {
|
||||
@ -3644,37 +3646,9 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
}
|
||||
}
|
||||
|
||||
if (warn) {
|
||||
warning("HugeTLBFS is not configured or not supported by the operating system.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool os::Linux::shm_hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
// Try to create a large shared memory segment.
|
||||
int shmid = shmget(IPC_PRIVATE, page_size, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
|
||||
if (shmid == -1) {
|
||||
// Possible reasons for shmget failure:
|
||||
// 1. shmmax is too small for the request.
|
||||
// > check shmmax value: cat /proc/sys/kernel/shmmax
|
||||
// > increase shmmax value: echo "new_value" > /proc/sys/kernel/shmmax
|
||||
// 2. not enough large page memory.
|
||||
// > check available large pages: cat /proc/meminfo
|
||||
// > increase amount of large pages:
|
||||
// sysctl -w vm.nr_hugepages=new_value
|
||||
// > For more information regarding large pages please refer to:
|
||||
// https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
|
||||
if (warn) {
|
||||
warning("Large pages using UseSHM are not configured on this system.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Managed to create a segment, now delete it.
|
||||
shmctl(shmid, IPC_RMID, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// From the coredump_filter documentation:
|
||||
//
|
||||
// - (bit 0) anonymous private memory
|
||||
@ -3722,56 +3696,13 @@ void warn_no_large_pages_configured() {
|
||||
}
|
||||
}
|
||||
|
||||
bool os::Linux::setup_large_page_type(size_t page_size) {
|
||||
if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
|
||||
FLAG_IS_DEFAULT(UseSHM) &&
|
||||
FLAG_IS_DEFAULT(UseTransparentHugePages)) {
|
||||
|
||||
// The type of large pages has not been specified by the user.
|
||||
|
||||
// Try UseHugeTLBFS and then UseSHM.
|
||||
UseHugeTLBFS = UseSHM = true;
|
||||
|
||||
// Don't try UseTransparentHugePages since there are known
|
||||
// performance issues with it turned on. This might change in the future.
|
||||
UseTransparentHugePages = false;
|
||||
}
|
||||
|
||||
if (UseTransparentHugePages) {
|
||||
UseHugeTLBFS = false;
|
||||
UseSHM = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (UseHugeTLBFS) {
|
||||
bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
|
||||
if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
|
||||
UseSHM = false;
|
||||
return true;
|
||||
}
|
||||
UseHugeTLBFS = false;
|
||||
}
|
||||
|
||||
if (UseSHM) {
|
||||
bool warn_on_failure = !FLAG_IS_DEFAULT(UseSHM);
|
||||
if (shm_hugetlbfs_sanity_check(warn_on_failure, page_size)) {
|
||||
return true;
|
||||
}
|
||||
UseSHM = false;
|
||||
}
|
||||
|
||||
warn_no_large_pages_configured();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct LargePageInitializationLoggerMark {
|
||||
~LargePageInitializationLoggerMark() {
|
||||
LogTarget(Info, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
if (UseLargePages) {
|
||||
ls.print_cr("UseLargePages=1, UseTransparentHugePages=%d, UseHugeTLBFS=%d, UseSHM=%d",
|
||||
UseTransparentHugePages, UseHugeTLBFS, UseSHM);
|
||||
ls.print_cr("UseLargePages=1, UseTransparentHugePages=%d", UseTransparentHugePages);
|
||||
ls.print("Large page support enabled. Usable page sizes: ");
|
||||
os::page_sizes().print_on(&ls);
|
||||
ls.print_cr(". Default large page size: " EXACTFMT ".", EXACTFMTARGS(os::large_page_size()));
|
||||
@ -3805,19 +3736,14 @@ void os::large_page_init() {
|
||||
|
||||
// 1) Handle the case where we do not want to use huge pages
|
||||
if (!UseLargePages &&
|
||||
!UseTransparentHugePages &&
|
||||
!UseHugeTLBFS &&
|
||||
!UseSHM) {
|
||||
!UseTransparentHugePages) {
|
||||
// Not using large pages.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages) {
|
||||
// The user explicitly turned off large pages.
|
||||
// Ignore the rest of the large pages flags.
|
||||
UseTransparentHugePages = false;
|
||||
UseHugeTLBFS = false;
|
||||
UseSHM = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3826,12 +3752,12 @@ void os::large_page_init() {
|
||||
if (!FLAG_IS_DEFAULT(UseTransparentHugePages)) {
|
||||
log_warning(pagesize)("UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system.");
|
||||
}
|
||||
UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false;
|
||||
UseLargePages = UseTransparentHugePages = false;
|
||||
return;
|
||||
}
|
||||
if (!UseTransparentHugePages && !HugePages::supports_static_hugepages()) {
|
||||
warn_no_large_pages_configured();
|
||||
UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false;
|
||||
UseLargePages = UseTransparentHugePages = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3855,6 +3781,8 @@ void os::large_page_init() {
|
||||
|
||||
// 3) Consistency check and post-processing
|
||||
|
||||
size_t large_page_size = 0;
|
||||
|
||||
// Check LargePageSizeInBytes matches an available page size and if so set _large_page_size
|
||||
// using LargePageSizeInBytes as the maximum allowed large page size. If LargePageSizeInBytes
|
||||
// doesn't match an available page size set _large_page_size to default_large_page_size
|
||||
@ -3862,30 +3790,40 @@ void os::large_page_init() {
|
||||
if (FLAG_IS_DEFAULT(LargePageSizeInBytes) ||
|
||||
LargePageSizeInBytes == 0 ||
|
||||
LargePageSizeInBytes == default_large_page_size) {
|
||||
_large_page_size = default_large_page_size;
|
||||
large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
byte_size_in_exact_unit(large_page_size),
|
||||
exact_unit_for_byte_size(large_page_size));
|
||||
} else {
|
||||
if (all_large_pages.contains(LargePageSizeInBytes)) {
|
||||
_large_page_size = LargePageSizeInBytes;
|
||||
large_page_size = LargePageSizeInBytes;
|
||||
log_info(pagesize)("Overriding default large page size (" SIZE_FORMAT "%s) "
|
||||
"using LargePageSizeInBytes: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(default_large_page_size),
|
||||
exact_unit_for_byte_size(default_large_page_size),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
byte_size_in_exact_unit(large_page_size),
|
||||
exact_unit_for_byte_size(large_page_size));
|
||||
} else {
|
||||
_large_page_size = default_large_page_size;
|
||||
large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("LargePageSizeInBytes is not a valid large page size (" SIZE_FORMAT "%s) "
|
||||
"using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(LargePageSizeInBytes),
|
||||
exact_unit_for_byte_size(LargePageSizeInBytes),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
byte_size_in_exact_unit(large_page_size),
|
||||
exact_unit_for_byte_size(large_page_size));
|
||||
}
|
||||
}
|
||||
|
||||
// Do an additional sanity check to see if we can use the desired large page size
|
||||
if (!hugetlbfs_sanity_check(large_page_size)) {
|
||||
warn_no_large_pages_configured();
|
||||
UseLargePages = false;
|
||||
UseTransparentHugePages = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_large_page_size = large_page_size;
|
||||
|
||||
// Populate _page_sizes with large page sizes less than or equal to
|
||||
// _large_page_size.
|
||||
for (size_t page_size = _large_page_size; page_size != 0;
|
||||
@ -3894,156 +3832,9 @@ void os::large_page_init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Now determine the type of large pages to use:
|
||||
UseLargePages = os::Linux::setup_large_page_type(_large_page_size);
|
||||
|
||||
set_coredump_filter(LARGEPAGES_BIT);
|
||||
}
|
||||
|
||||
#ifndef SHM_HUGETLB
|
||||
#define SHM_HUGETLB 04000
|
||||
#endif
|
||||
|
||||
#define shm_warning_format(format, ...) \
|
||||
do { \
|
||||
if (UseLargePages && \
|
||||
(!FLAG_IS_DEFAULT(UseLargePages) || \
|
||||
!FLAG_IS_DEFAULT(UseSHM) || \
|
||||
!FLAG_IS_DEFAULT(LargePageSizeInBytes))) { \
|
||||
warning(format, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define shm_warning(str) shm_warning_format("%s", str)
|
||||
|
||||
#define shm_warning_with_errno(str) \
|
||||
do { \
|
||||
int err = errno; \
|
||||
shm_warning_format(str " (error = %d)", err); \
|
||||
} while (0)
|
||||
|
||||
static char* shmat_with_alignment(int shmid, size_t bytes, size_t alignment) {
|
||||
assert(is_aligned(bytes, alignment), "Must be divisible by the alignment");
|
||||
|
||||
if (!is_aligned(alignment, SHMLBA)) {
|
||||
assert(false, "Code below assumes that alignment is at least SHMLBA aligned");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// To ensure that we get 'alignment' aligned memory from shmat,
|
||||
// we pre-reserve aligned virtual memory and then attach to that.
|
||||
|
||||
char* pre_reserved_addr = anon_mmap_aligned(nullptr /* req_addr */, bytes, alignment);
|
||||
if (pre_reserved_addr == nullptr) {
|
||||
// Couldn't pre-reserve aligned memory.
|
||||
shm_warning("Failed to pre-reserve aligned memory for shmat.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// SHM_REMAP is needed to allow shmat to map over an existing mapping.
|
||||
char* addr = (char*)shmat(shmid, pre_reserved_addr, SHM_REMAP);
|
||||
|
||||
if ((intptr_t)addr == -1) {
|
||||
int err = errno;
|
||||
shm_warning_with_errno("Failed to attach shared memory.");
|
||||
|
||||
assert(err != EACCES, "Unexpected error");
|
||||
assert(err != EIDRM, "Unexpected error");
|
||||
assert(err != EINVAL, "Unexpected error");
|
||||
|
||||
// Since we don't know if the kernel unmapped the pre-reserved memory area
|
||||
// we can't unmap it, since that would potentially unmap memory that was
|
||||
// mapped from other threads.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static char* shmat_at_address(int shmid, char* req_addr) {
|
||||
if (!is_aligned(req_addr, SHMLBA)) {
|
||||
assert(false, "Requested address needs to be SHMLBA aligned");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* addr = (char*)shmat(shmid, req_addr, 0);
|
||||
|
||||
if ((intptr_t)addr == -1) {
|
||||
shm_warning_with_errno("Failed to attach shared memory.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static char* shmat_large_pages(int shmid, size_t bytes, size_t alignment, char* req_addr) {
|
||||
// If a req_addr has been provided, we assume that the caller has already aligned the address.
|
||||
if (req_addr != nullptr) {
|
||||
assert(is_aligned(req_addr, os::large_page_size()), "Must be divisible by the large page size");
|
||||
assert(is_aligned(req_addr, alignment), "Must be divisible by given alignment");
|
||||
return shmat_at_address(shmid, req_addr);
|
||||
}
|
||||
|
||||
// Since shmid has been setup with SHM_HUGETLB, shmat will automatically
|
||||
// return large page size aligned memory addresses when req_addr == nullptr.
|
||||
// However, if the alignment is larger than the large page size, we have
|
||||
// to manually ensure that the memory returned is 'alignment' aligned.
|
||||
if (alignment > os::large_page_size()) {
|
||||
assert(is_aligned(alignment, os::large_page_size()), "Must be divisible by the large page size");
|
||||
return shmat_with_alignment(shmid, bytes, alignment);
|
||||
} else {
|
||||
return shmat_at_address(shmid, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment,
|
||||
char* req_addr, bool exec) {
|
||||
// "exec" is passed in but not used. Creating the shared image for
|
||||
// the code cache doesn't have an SHM_X executable permission to check.
|
||||
assert(UseLargePages && UseSHM, "only for SHM large pages");
|
||||
assert(is_aligned(req_addr, os::large_page_size()), "Unaligned address");
|
||||
assert(is_aligned(req_addr, alignment), "Unaligned address");
|
||||
|
||||
if (!is_aligned(bytes, os::large_page_size())) {
|
||||
return nullptr; // Fallback to small pages.
|
||||
}
|
||||
|
||||
// Create a large shared memory region to attach to based on size.
|
||||
// Currently, size is the total size of the heap.
|
||||
int shmid = shmget(IPC_PRIVATE, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
|
||||
if (shmid == -1) {
|
||||
// Possible reasons for shmget failure:
|
||||
// 1. shmmax is too small for the request.
|
||||
// > check shmmax value: cat /proc/sys/kernel/shmmax
|
||||
// > increase shmmax value: echo "new_value" > /proc/sys/kernel/shmmax
|
||||
// 2. not enough large page memory.
|
||||
// > check available large pages: cat /proc/meminfo
|
||||
// > increase amount of large pages:
|
||||
// sysctl -w vm.nr_hugepages=new_value
|
||||
// > For more information regarding large pages please refer to:
|
||||
// https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
|
||||
// Note 1: different Linux may use different name for this property,
|
||||
// e.g. on Redhat AS-3 it is "hugetlb_pool".
|
||||
// Note 2: it's possible there's enough physical memory available but
|
||||
// they are so fragmented after a long run that they can't
|
||||
// coalesce into large pages. Try to reserve large pages when
|
||||
// the system is still "fresh".
|
||||
shm_warning_with_errno("Failed to reserve shared memory.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Attach to the region.
|
||||
char* addr = shmat_large_pages(shmid, bytes, alignment, req_addr);
|
||||
|
||||
// Remove shmid. If shmat() is successful, the actual shared memory segment
|
||||
// will be deleted when it's detached by shmdt() or when the process
|
||||
// terminates. If shmat() is not successful this will remove the shared
|
||||
// segment immediately.
|
||||
shmctl(shmid, IPC_RMID, nullptr);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
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");
|
||||
@ -4054,11 +3845,11 @@ static void log_on_commit_special_failure(char* req_addr, size_t 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,
|
||||
static bool commit_memory_special(size_t bytes,
|
||||
size_t page_size,
|
||||
char* req_addr,
|
||||
bool exec) {
|
||||
assert(UseLargePages && UseHugeTLBFS, "Should only get here when HugeTLBFS large pages are used");
|
||||
assert(UseLargePages && !UseTransparentHugePages, "Should only get here for static hugepage mode (+UseLargePages)");
|
||||
assert(is_aligned(bytes, page_size), "Unaligned size");
|
||||
assert(is_aligned(req_addr, page_size), "Unaligned address");
|
||||
assert(req_addr != nullptr, "Must have a requested address for special mappings");
|
||||
@ -4087,16 +3878,17 @@ bool os::Linux::commit_memory_special(size_t bytes,
|
||||
return true;
|
||||
}
|
||||
|
||||
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");
|
||||
static char* reserve_memory_special_huge_tlbfs(size_t bytes,
|
||||
size_t alignment,
|
||||
size_t page_size,
|
||||
char* req_addr,
|
||||
bool exec) {
|
||||
const os::PageSizes page_sizes = HugePages::static_info().pagesizes();
|
||||
assert(UseLargePages, "only for Huge TLBFS large pages");
|
||||
assert(is_aligned(req_addr, alignment), "Must be");
|
||||
assert(is_aligned(req_addr, page_size), "Must be");
|
||||
assert(is_aligned(alignment, os::vm_allocation_granularity()), "Must be");
|
||||
assert(_page_sizes.contains(page_size), "Must be a valid page size");
|
||||
assert(page_sizes.contains(page_size), "Must be a valid page size");
|
||||
assert(page_size > os::vm_page_size(), "Must be a large page size");
|
||||
assert(bytes >= page_size, "Shouldn't allocate large pages for small sizes");
|
||||
|
||||
@ -4149,14 +3941,7 @@ char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_
|
||||
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, page_size, req_addr, exec);
|
||||
}
|
||||
char* const addr = reserve_memory_special_huge_tlbfs(bytes, alignment, page_size, req_addr, exec);
|
||||
|
||||
if (addr != nullptr) {
|
||||
if (UseNUMAInterleaving) {
|
||||
@ -4167,45 +3952,29 @@ char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
|
||||
// detaching the SHM segment will also delete it, see reserve_memory_special_shm()
|
||||
return shmdt(base) == 0;
|
||||
}
|
||||
|
||||
bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
|
||||
return pd_release_memory(base, bytes);
|
||||
}
|
||||
|
||||
bool os::pd_release_memory_special(char* base, size_t bytes) {
|
||||
assert(UseLargePages, "only for large pages");
|
||||
bool res;
|
||||
|
||||
if (UseSHM) {
|
||||
res = os::Linux::release_memory_special_shm(base, bytes);
|
||||
} else {
|
||||
assert(UseHugeTLBFS, "must be");
|
||||
res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
|
||||
}
|
||||
return res;
|
||||
// Plain munmap is sufficient
|
||||
return pd_release_memory(base, bytes);
|
||||
}
|
||||
|
||||
size_t os::large_page_size() {
|
||||
return _large_page_size;
|
||||
}
|
||||
|
||||
// With SysV SHM the entire memory region must be allocated as shared
|
||||
// memory.
|
||||
// HugeTLBFS allows application to commit large page memory on demand.
|
||||
// However, when committing memory with HugeTLBFS fails, the region
|
||||
// static hugepages (hugetlbfs) allow application to commit large page memory
|
||||
// on demand.
|
||||
// However, when committing memory with hugepages fails, the region
|
||||
// that was supposed to be committed will lose the old reservation
|
||||
// and allow other threads to steal that memory region. Because of this
|
||||
// behavior we can't commit HugeTLBFS memory.
|
||||
// behavior we can't commit hugetlbfs memory. Instead, we commit that
|
||||
// memory at reservation.
|
||||
bool os::can_commit_large_page_memory() {
|
||||
return UseTransparentHugePages;
|
||||
}
|
||||
|
||||
bool os::can_execute_large_page_memory() {
|
||||
return UseTransparentHugePages || UseHugeTLBFS;
|
||||
return UseTransparentHugePages;
|
||||
}
|
||||
|
||||
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
|
||||
@ -4561,12 +4330,11 @@ void os::Linux::numa_init() {
|
||||
}
|
||||
|
||||
if (UseParallelGC && UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
|
||||
// With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
|
||||
// With static large pages we cannot uncommit a page, so there's no way
|
||||
// we can make the adaptive lgrp chunk resizing work. If the user specified both
|
||||
// UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn
|
||||
// and disable adaptive resizing.
|
||||
// UseNUMA and UseLargePages on the command line - warn and disable adaptive resizing.
|
||||
if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
|
||||
warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, "
|
||||
warning("UseNUMA is not fully compatible with +UseLargePages, "
|
||||
"disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
|
||||
UseAdaptiveSizePolicy = false;
|
||||
UseAdaptiveNUMAChunkSizing = false;
|
||||
|
@ -33,7 +33,6 @@ class os::Linux {
|
||||
friend class CgroupSubsystem;
|
||||
friend class os;
|
||||
friend class OSContainer;
|
||||
friend class TestReserveMemorySpecial;
|
||||
|
||||
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
|
||||
static int (*_pthread_setname_np)(pthread_t, const char*);
|
||||
@ -75,20 +74,6 @@ class os::Linux {
|
||||
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
|
||||
static GrowableArray<int>* nindex_to_node() { return _nindex_to_node; }
|
||||
|
||||
static bool setup_large_page_type(size_t page_size);
|
||||
static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
|
||||
static bool shm_hugetlbfs_sanity_check(bool warn, size_t page_size);
|
||||
|
||||
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, 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);
|
||||
static bool release_memory_special_shm(char* base, size_t bytes);
|
||||
static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
|
||||
|
||||
static void print_process_memory_info(outputStream* st);
|
||||
static void print_system_memory_info(outputStream* st);
|
||||
static bool print_container_info(outputStream* st);
|
||||
|
@ -526,6 +526,11 @@ static SpecialFlag const special_jvm_flags[] = {
|
||||
{ "MetaspaceReclaimPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
|
||||
{ "DoReserveCopyInSuperWord", JDK_Version::undefined(), JDK_Version::jdk(22), JDK_Version::jdk(23) },
|
||||
|
||||
#ifdef LINUX
|
||||
{ "UseHugeTLBFS", JDK_Version::undefined(), JDK_Version::jdk(22), JDK_Version::jdk(23) },
|
||||
{ "UseSHM", JDK_Version::undefined(), JDK_Version::jdk(22), JDK_Version::jdk(23) },
|
||||
#endif
|
||||
|
||||
#ifdef ASSERT
|
||||
{ "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() },
|
||||
#endif
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
static bool using_static_hugepages() { return UseLargePages && !UseTransparentHugePages; }
|
||||
|
||||
namespace {
|
||||
static void small_page_write(void* addr, size_t size) {
|
||||
@ -53,29 +54,16 @@ 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::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, page_size, req_addr, exec);
|
||||
return os::reserve_memory_special(bytes, alignment, page_size, req_addr, exec);
|
||||
}
|
||||
HugeTlbfsMemory(char* const ptr, size_t size) : _ptr(ptr), _size(size) { }
|
||||
~HugeTlbfsMemory() {
|
||||
if (_ptr != NULL) {
|
||||
os::Linux::release_memory_special_huge_tlbfs(_ptr, _size);
|
||||
os::release_memory_special(_ptr, _size);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ShmMemory : private ::os::Linux {
|
||||
char* const _ptr;
|
||||
const size_t _size;
|
||||
public:
|
||||
static char* reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec) {
|
||||
return os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
|
||||
}
|
||||
ShmMemory(char* const ptr, size_t size) : _ptr(ptr), _size(size) { }
|
||||
~ShmMemory() {
|
||||
os::Linux::release_memory_special_shm(_ptr, _size);
|
||||
}
|
||||
};
|
||||
|
||||
// have to use these functions, as gtest's _PRED macros don't like is_aligned
|
||||
// nor (is_aligned<size_t, size_t>)
|
||||
static bool is_size_aligned(size_t size, size_t alignment) {
|
||||
@ -84,22 +72,10 @@ namespace {
|
||||
static bool is_ptr_aligned(char* ptr, size_t alignment) {
|
||||
return is_aligned(ptr, alignment);
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
|
||||
ASSERT_TRUE(UseSHM) << "must be used only when UseSHM is true";
|
||||
char* addr = ShmMemory::reserve_memory_special_shm(size, alignment, NULL, false);
|
||||
if (addr != NULL) {
|
||||
ShmMemory mr(addr, size);
|
||||
EXPECT_PRED2(is_ptr_aligned, addr, alignment);
|
||||
EXPECT_PRED2(is_ptr_aligned, addr, os::large_page_size());
|
||||
|
||||
small_page_write(addr, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_aligned) {
|
||||
if (!UseHugeTLBFS) {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
size_t lp = os::large_page_size();
|
||||
@ -115,7 +91,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_aligned) {
|
||||
}
|
||||
|
||||
TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_without_addr) {
|
||||
if (!UseHugeTLBFS) {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
size_t lp = os::large_page_size();
|
||||
@ -142,7 +118,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_without_add
|
||||
}
|
||||
|
||||
TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_with_good_req_addr) {
|
||||
if (!UseHugeTLBFS) {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
size_t lp = os::large_page_size();
|
||||
@ -183,7 +159,7 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_with_good_r
|
||||
|
||||
|
||||
TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_with_bad_req_addr) {
|
||||
if (!UseHugeTLBFS) {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
size_t lp = os::large_page_size();
|
||||
@ -233,20 +209,6 @@ TEST_VM(os_linux, reserve_memory_special_huge_tlbfs_size_not_aligned_with_bad_re
|
||||
}
|
||||
}
|
||||
|
||||
TEST_VM(os_linux, reserve_memory_special_shm) {
|
||||
if (!UseSHM) {
|
||||
return;
|
||||
}
|
||||
size_t lp = os::large_page_size();
|
||||
size_t ag = os::vm_allocation_granularity();
|
||||
|
||||
for (size_t size = ag; size < lp * 3; size += ag) {
|
||||
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
|
||||
EXPECT_NO_FATAL_FAILURE(test_reserve_memory_special_shm(size, alignment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestReserveMemorySpecial : AllStatic {
|
||||
public:
|
||||
static void small_page_write(void* addr, size_t size) {
|
||||
@ -259,26 +221,21 @@ class TestReserveMemorySpecial : AllStatic {
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs_size_aligned(size_t size, size_t alignment, size_t page_size) {
|
||||
if (!UseHugeTLBFS) {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
|
||||
char* addr = os::Linux::reserve_memory_special_huge_tlbfs(size, alignment, page_size, NULL, false);
|
||||
|
||||
char* addr = os::reserve_memory_special(size, alignment, page_size, NULL, false);
|
||||
if (addr != NULL) {
|
||||
small_page_write(addr, size);
|
||||
|
||||
os::Linux::release_memory_special_huge_tlbfs(addr, size);
|
||||
os::release_memory_special(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs_size_aligned() {
|
||||
if (!UseHugeTLBFS) {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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, lp);
|
||||
}
|
||||
@ -324,11 +281,11 @@ 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, lp, NULL, false);
|
||||
char* p = os::reserve_memory_special(size, alignment, lp, NULL, false);
|
||||
if (p != NULL) {
|
||||
EXPECT_TRUE(is_aligned(p, alignment));
|
||||
small_page_write(p, size);
|
||||
os::Linux::release_memory_special_huge_tlbfs(p, size);
|
||||
os::release_memory_special(p, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,11 +296,11 @@ 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, lp, req_addr, false);
|
||||
char* p = os::reserve_memory_special(size, alignment, lp, req_addr, false);
|
||||
if (p != NULL) {
|
||||
EXPECT_EQ(p, req_addr);
|
||||
small_page_write(p, size);
|
||||
os::Linux::release_memory_special_huge_tlbfs(p, size);
|
||||
os::release_memory_special(p, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -354,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::Linux::reserve_memory_special_huge_tlbfs(size, alignment, lp, req_addr, false);
|
||||
char* p = os::reserve_memory_special(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);
|
||||
@ -365,47 +322,13 @@ class TestReserveMemorySpecial : AllStatic {
|
||||
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs() {
|
||||
if (!UseHugeTLBFS) {
|
||||
static void test() {
|
||||
if (!using_static_hugepages()) {
|
||||
return;
|
||||
}
|
||||
|
||||
test_reserve_memory_special_huge_tlbfs_size_aligned();
|
||||
test_reserve_memory_special_huge_tlbfs_size_not_aligned();
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
|
||||
if (!UseSHM) {
|
||||
return;
|
||||
}
|
||||
|
||||
char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
|
||||
|
||||
if (addr != NULL) {
|
||||
EXPECT_TRUE(is_aligned(addr, alignment));
|
||||
EXPECT_TRUE(is_aligned(addr, os::large_page_size()));
|
||||
|
||||
small_page_write(addr, size);
|
||||
|
||||
os::Linux::release_memory_special_shm(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_shm() {
|
||||
size_t lp = os::large_page_size();
|
||||
size_t ag = os::vm_allocation_granularity();
|
||||
|
||||
for (size_t size = ag; size < lp * 3; size += ag) {
|
||||
for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
|
||||
test_reserve_memory_special_shm(size, alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test() {
|
||||
test_reserve_memory_special_huge_tlbfs();
|
||||
test_reserve_memory_special_shm();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_VM(os_linux, reserve_memory_special) {
|
||||
|
@ -35,7 +35,7 @@ package gc.arguments;
|
||||
* @modules java.management/sun.management
|
||||
* @build TestSmallInitialHeapWithLargePageAndNUMA
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UseHugeTLBFS -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.arguments.TestSmallInitialHeapWithLargePageAndNUMA
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.arguments.TestSmallInitialHeapWithLargePageAndNUMA
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
@ -65,7 +65,6 @@ public class TestSmallInitialHeapWithLargePageAndNUMA {
|
||||
"-Xms" + String.valueOf(initHeap),
|
||||
"-Xmx" + String.valueOf(maxHeap),
|
||||
"-XX:+UseNUMA",
|
||||
"-XX:+UseHugeTLBFS",
|
||||
"-XX:+PrintFlagsFinal",
|
||||
"-version");
|
||||
OutputAnalyzer analyzer = new OutputAnalyzer(pb_enabled.start());
|
||||
|
@ -55,13 +55,3 @@
|
||||
* @requires vm.flagless
|
||||
* @run main/native GTestWrapper --gtest_filter=os* -XX:-PrintWarnings -XX:+UseLargePages -XX:LargePageSizeInBytes=1G
|
||||
*/
|
||||
|
||||
/* @test id=use-large-pages-sysV
|
||||
* @summary Run metaspace-related gtests for reclaim policy none (with verifications)
|
||||
* @requires os.family == "linux"
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.xml
|
||||
* @requires vm.flagless
|
||||
* @run main/native GTestWrapper --gtest_filter=os* -XX:-PrintWarnings -XX:+UseLargePages -XX:+UseSHM
|
||||
*/
|
||||
|
@ -43,9 +43,6 @@ public class TestLargePagesFlags {
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
testUseTransparentHugePages();
|
||||
testUseHugeTLBFS();
|
||||
testUseSHM();
|
||||
testCombinations();
|
||||
}
|
||||
|
||||
public static void testUseTransparentHugePages() throws Exception {
|
||||
@ -60,27 +57,21 @@ public class TestLargePagesFlags {
|
||||
UseTransparentHugePages(true))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
UseTransparentHugePages(false));
|
||||
|
||||
// Explicitly turn on UseTransparentHugePages.
|
||||
new FlagTester()
|
||||
.use(UseTransparentHugePages(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(true),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
UseTransparentHugePages(true));
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseTransparentHugePages(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(true),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
UseTransparentHugePages(true));
|
||||
|
||||
// Setting a specific large pages flag will turn
|
||||
// off heuristics to choose large pages type.
|
||||
@ -89,9 +80,7 @@ public class TestLargePagesFlags {
|
||||
UseTransparentHugePages(false))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
UseTransparentHugePages(false));
|
||||
|
||||
// Don't turn on UseTransparentHugePages
|
||||
// unless the user explicitly asks for them.
|
||||
@ -101,192 +90,6 @@ public class TestLargePagesFlags {
|
||||
UseTransparentHugePages(false));
|
||||
}
|
||||
|
||||
public static void testUseHugeTLBFS() throws Exception {
|
||||
if (!canUse(UseHugeTLBFS(true))) {
|
||||
System.out.println("Skipping testUseHugeTLBFS");
|
||||
return;
|
||||
}
|
||||
|
||||
// -XX:-UseLargePages overrides all other flags.
|
||||
new FlagTester()
|
||||
.use(UseLargePages(false),
|
||||
UseHugeTLBFS(true))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
|
||||
// Explicitly turn on UseHugeTLBFS.
|
||||
new FlagTester()
|
||||
.use(UseHugeTLBFS(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(false));
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseHugeTLBFS(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(false));
|
||||
|
||||
// Setting a specific large pages flag will turn
|
||||
// off heuristics to choose large pages type.
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseHugeTLBFS(false))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
|
||||
// Using UseLargePages will default to UseHugeTLBFS large pages.
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(false));
|
||||
}
|
||||
|
||||
public static void testUseSHM() throws Exception {
|
||||
if (!canUse(UseSHM(true))) {
|
||||
System.out.println("Skipping testUseSHM");
|
||||
return;
|
||||
}
|
||||
|
||||
// -XX:-UseLargePages overrides all other flags.
|
||||
new FlagTester()
|
||||
.use(UseLargePages(false),
|
||||
UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
|
||||
// Explicitly turn on UseSHM.
|
||||
new FlagTester()
|
||||
.use(UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(true)) ;
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(true)) ;
|
||||
|
||||
// Setting a specific large pages flag will turn
|
||||
// off heuristics to choose large pages type.
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseSHM(false))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
|
||||
// Setting UseLargePages can allow the system to choose
|
||||
// UseHugeTLBFS instead of UseSHM, but never UseTransparentHugePages.
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false));
|
||||
}
|
||||
|
||||
public static void testCombinations() throws Exception {
|
||||
if (!canUse(UseSHM(true)) || !canUse(UseHugeTLBFS(true))) {
|
||||
System.out.println("Skipping testUseHugeTLBFSAndUseSHMCombination");
|
||||
return;
|
||||
}
|
||||
|
||||
// UseHugeTLBFS takes precedence over SHM.
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(false));
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(true));
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(false))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(false));
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false))
|
||||
.expect(
|
||||
UseLargePages(false),
|
||||
UseTransparentHugePages(false),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
|
||||
|
||||
if (!canUse(UseTransparentHugePages(true))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// UseTransparentHugePages takes precedence.
|
||||
|
||||
new FlagTester()
|
||||
.use(UseLargePages(true),
|
||||
UseTransparentHugePages(true),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(true),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
|
||||
new FlagTester()
|
||||
.use(UseTransparentHugePages(true),
|
||||
UseHugeTLBFS(true),
|
||||
UseSHM(true))
|
||||
.expect(
|
||||
UseLargePages(true),
|
||||
UseTransparentHugePages(true),
|
||||
UseHugeTLBFS(false),
|
||||
UseSHM(false));
|
||||
}
|
||||
|
||||
private static class FlagTester {
|
||||
private Flag [] useFlags;
|
||||
|
||||
@ -304,6 +107,7 @@ public class TestLargePagesFlags {
|
||||
System.out.println("Expecting: " + Arrays.toString(expectedFlags));
|
||||
|
||||
OutputAnalyzer output = executeNewJVM(useFlags);
|
||||
output.reportDiagnosticSummary();
|
||||
|
||||
for (Flag flag : expectedFlags) {
|
||||
System.out.println("Looking for: " + flag.flagString());
|
||||
@ -329,7 +133,7 @@ public class TestLargePagesFlags {
|
||||
for (Flag flag : flags) {
|
||||
args.add(flag.flagString());
|
||||
}
|
||||
args.add("-XX:+PrintFlagsFinal");
|
||||
args.add("-Xlog:pagesize");
|
||||
args.add("-version");
|
||||
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
@ -357,14 +161,6 @@ public class TestLargePagesFlags {
|
||||
return new BooleanFlag("UseTransparentHugePages", value);
|
||||
}
|
||||
|
||||
private static Flag UseHugeTLBFS(boolean value) {
|
||||
return new BooleanFlag("UseHugeTLBFS", value);
|
||||
}
|
||||
|
||||
private static Flag UseSHM(boolean value) {
|
||||
return new BooleanFlag("UseSHM", value);
|
||||
}
|
||||
|
||||
private static class BooleanFlag implements Flag {
|
||||
private String name;
|
||||
private boolean value;
|
||||
|
Loading…
Reference in New Issue
Block a user