@@ -22,6 +22,7 @@
*/
#include " precompiled.hpp"
#include " gc/shared/gcLogPrecious.hpp"
#include " gc/z/zArray.inline.hpp"
#include " gc/z/zErrno.hpp"
#include " gc/z/zGlobals.hpp"
@@ -130,58 +131,58 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking() :
struct statfs buf;
if (fstatfs (_fd, &buf) == -1 ) {
ZErrno err;
log_error (gc)(" Failed to determine filesystem type for backing file (%s)" , err.to_string ());
log_error_p (gc)(" Failed to determine filesystem type for backing file (%s)" , err.to_string ());
return ;
}
_filesystem = buf.f_type ;
_block_size = buf.f_bsize ;
_available = buf.f_bavail * _block_size;
log_info (gc, init)(" Heap Backing Filesystem: %s (0x" UINT64_FORMAT_X " )" ,
is_tmpfs () ? ZFILESYSTEM_TMPFS : is_hugetlbfs () ? ZFILESYSTEM_HUGETLBFS : " other" , _filesystem);
log_info_p (gc, init)(" Heap Backing Filesystem: %s (0x" UINT64_FORMAT_X " )" ,
is_tmpfs () ? ZFILESYSTEM_TMPFS : is_hugetlbfs () ? ZFILESYSTEM_HUGETLBFS : " other" , _filesystem);
// Make sure the filesystem type matches requested large page type
if (ZLargePages::is_transparent () && !is_tmpfs ()) {
log_error (gc)(" -XX:+UseTransparentHugePages can only be enabled when using a %s filesystem" ,
ZFILESYSTEM_TMPFS);
log_error_p (gc)(" -XX:+UseTransparentHugePages can only be enabled when using a %s filesystem" ,
ZFILESYSTEM_TMPFS);
return ;
}
if (ZLargePages::is_transparent () && !tmpfs_supports_transparent_huge_pages ()) {
log_error (gc)(" -XX:+UseTransparentHugePages on a %s filesystem not supported by kernel" ,
ZFILESYSTEM_TMPFS);
log_error_p (gc)(" -XX:+UseTransparentHugePages on a %s filesystem not supported by kernel" ,
ZFILESYSTEM_TMPFS);
return ;
}
if (ZLargePages::is_explicit () && !is_hugetlbfs ()) {
log_error (gc)(" -XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled "
" when using a %s filesystem" , ZFILESYSTEM_HUGETLBFS);
log_error_p (gc)(" -XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled "
" when using a %s filesystem" , ZFILESYSTEM_HUGETLBFS);
return ;
}
if (!ZLargePages::is_explicit () && is_hugetlbfs ()) {
log_error (gc)(" -XX:+UseLargePages must be enabled when using a %s filesystem" ,
ZFILESYSTEM_HUGETLBFS);
log_error_p (gc)(" -XX:+UseLargePages must be enabled when using a %s filesystem" ,
ZFILESYSTEM_HUGETLBFS);
return ;
}
if (ZLargePages::is_explicit () && os::large_page_size () != ZGranuleSize) {
log_error (gc)(" Incompatible large page size configured " SIZE_FORMAT " (expected " SIZE_FORMAT " )" ,
os::large_page_size (), ZGranuleSize);
log_error_p (gc)(" Incompatible large page size configured " SIZE_FORMAT " (expected " SIZE_FORMAT " )" ,
os::large_page_size (), ZGranuleSize);
return ;
}
// Make sure the filesystem block size is compatible
if (ZGranuleSize % _block_size != 0 ) {
log_error (gc)(" Filesystem backing the heap has incompatible block size (" SIZE_FORMAT " )" ,
_block_size);
log_error_p (gc)(" Filesystem backing the heap has incompatible block size (" SIZE_FORMAT " )" ,
_block_size);
return ;
}
if (is_hugetlbfs () && _block_size != ZGranuleSize) {
log_error (gc)(" %s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT " )" ,
ZFILESYSTEM_HUGETLBFS, _block_size, ZGranuleSize);
log_error_p (gc)(" %s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT " )" ,
ZFILESYSTEM_HUGETLBFS, _block_size, ZGranuleSize);
return ;
}
@@ -199,12 +200,12 @@ int ZPhysicalMemoryBacking::create_mem_fd(const char* name) const {
const int fd = ZSyscall::memfd_create (filename, MFD_CLOEXEC | extra_flags);
if (fd == -1 ) {
ZErrno err;
log_debug (gc, init)(" Failed to create memfd file (%s)" ,
((ZLargePages::is_explicit () && err == EINVAL) ? " Hugepages not supported" : err.to_string ()));
log_debug_p (gc, init)(" Failed to create memfd file (%s)" ,
((ZLargePages::is_explicit () && err == EINVAL) ? " Hugepages not supported" : err.to_string ()));
return -1 ;
}
log_info (gc, init)(" Heap Backing File: /memfd:%s" , filename);
log_info_p (gc, init)(" Heap Backing File: /memfd:%s" , filename);
return fd;
}
@@ -220,7 +221,7 @@ int ZPhysicalMemoryBacking::create_file_fd(const char* name) const {
// Find mountpoint
ZMountPoint mountpoint (filesystem, preferred_mountpoints);
if (mountpoint.get () == NULL ) {
log_error (gc)(" Use -XX:AllocateHeapAt to specify the path to a %s filesystem" , filesystem);
log_error_p (gc)(" Use -XX:AllocateHeapAt to specify the path to a %s filesystem" , filesystem);
return -1 ;
}
@@ -229,23 +230,23 @@ int ZPhysicalMemoryBacking::create_file_fd(const char* name) const {
const int fd_anon = os::open (mountpoint.get (), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
if (fd_anon == -1 ) {
ZErrno err;
log_debug (gc, init)(" Failed to create anonymous file in %s (%s)" , mountpoint.get (),
(err == EINVAL ? " Not supported" : err.to_string ()));
log_debug_p (gc, init)(" Failed to create anonymous file in %s (%s)" , mountpoint.get (),
(err == EINVAL ? " Not supported" : err.to_string ()));
} else {
// Get inode number for anonymous file
struct stat stat_buf;
if (fstat (fd_anon, &stat_buf) == -1 ) {
ZErrno err;
log_error (gc)(" Failed to determine inode number for anonymous file (%s)" , err.to_string ());
log_error_p (gc)(" Failed to determine inode number for anonymous file (%s)" , err.to_string ());
return -1 ;
}
log_info (gc, init)(" Heap Backing File: %s/#" UINT64_FORMAT, mountpoint.get (), (uint64_t )stat_buf.st_ino );
log_info_p (gc, init)(" Heap Backing File: %s/#" UINT64_FORMAT, mountpoint.get (), (uint64_t )stat_buf.st_ino );
return fd_anon;
}
log_debug (gc, init)(" Falling back to open/unlink" );
log_debug_p (gc, init)(" Falling back to open/unlink" );
// Create file name
char filename[PATH_MAX];
@@ -255,18 +256,18 @@ int ZPhysicalMemoryBacking::create_file_fd(const char* name) const {
const int fd = os::open (filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
if (fd == -1 ) {
ZErrno err;
log_error (gc)(" Failed to create file %s (%s)" , filename, err.to_string ());
log_error_p (gc)(" Failed to create file %s (%s)" , filename, err.to_string ());
return -1 ;
}
// Unlink file
if (unlink (filename) == -1 ) {
ZErrno err;
log_error (gc)(" Failed to unlink file %s (%s)" , filename, err.to_string ());
log_error_p (gc)(" Failed to unlink file %s (%s)" , filename, err.to_string ());
return -1 ;
}
log_info (gc, init)(" Heap Backing File: %s" , filename);
log_info_p (gc, init)(" Heap Backing File: %s" , filename);
return fd;
}
@@ -283,7 +284,7 @@ int ZPhysicalMemoryBacking::create_fd(const char* name) const {
return fd;
}
log_debug (gc, init )(" Falling back to searching for an accessible mount point" );
log_debug_p (gc)(" Falling back to searching for an accessible mount point" );
}
return create_file_fd (name);
@@ -298,23 +299,23 @@ void ZPhysicalMemoryBacking::warn_available_space(size_t max) const {
// will be zero if no size limit was specified when it was mounted.
if (_available == 0 ) {
// No size limit set, skip check
log_info (gc, init)(" Available space on backing filesystem: N/A" );
log_info_p (gc, init)(" Available space on backing filesystem: N/A" );
return ;
}
log_info (gc, init)(" Available space on backing filesystem: " SIZE_FORMAT " M" , _available / M);
log_info_p (gc, init)(" Available space on backing filesystem: " SIZE_FORMAT " M" , _available / M);
// Warn if the filesystem doesn't currently have enough space available to hold
// the max heap size. The max heap size will be capped if we later hit this limit
// when trying to expand the heap.
if (_available < max) {
log_warning (gc)(" ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****" );
log_warning (gc)(" Not enough space available on the backing filesystem to hold the current max Java heap" );
log_warning (gc)(" size (" SIZE_FORMAT " M). Please adjust the size of the backing filesystem accordingly "
log_warning_p (gc)(" ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****" );
log_warning_p (gc)(" Not enough space available on the backing filesystem to hold the current max Java heap" );
log_warning_p (gc)(" size (" SIZE_FORMAT " M). Please adjust the size of the backing filesystem accordingly "
" (available" , max / M);
log_warning (gc)(" space is currently " SIZE_FORMAT " M). Continuing execution with the current filesystem "
log_warning_p (gc)(" space is currently " SIZE_FORMAT " M). Continuing execution with the current filesystem "
" size could" , _available / M);
log_warning (gc)(" lead to a premature OutOfMemoryError being thrown, due to failure to map memory." );
log_warning_p (gc)(" lead to a premature OutOfMemoryError being thrown, due to failure to map memory." );
}
}
@@ -323,7 +324,7 @@ void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
FILE* const file = fopen (filename, " r" );
if (file == NULL ) {
// Failed to open file, skip check
log_debug (gc, init)(" Failed to open %s" , filename);
log_debug_p (gc, init)(" Failed to open %s" , filename);
return ;
}
@@ -332,7 +333,7 @@ void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
fclose (file);
if (result != 1 ) {
// Failed to read file, skip check
log_debug (gc, init)(" Failed to read %s" , filename);
log_debug_p (gc, init)(" Failed to read %s" , filename);
return ;
}
@@ -343,13 +344,13 @@ void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
// We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
const size_t required_max_map_count = (max / ZGranuleSize) * 3 * 1.2 ;
if (actual_max_map_count < required_max_map_count) {
log_warning (gc)(" ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****" );
log_warning (gc)(" The system limit on number of memory mappings per process might be too low for the given" );
log_warning (gc)(" max Java heap size (" SIZE_FORMAT " M). Please adjust %s to allow for at" ,
log_warning_p (gc)(" ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****" );
log_warning_p (gc)(" The system limit on number of memory mappings per process might be too low for the given" );
log_warning_p (gc)(" max Java heap size (" SIZE_FORMAT " M). Please adjust %s to allow for at" ,
max / M, filename);
log_warning (gc)(" least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT " ). Continuing execution "
log_warning_p (gc)(" least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT " ). Continuing execution "
" with the current" , required_max_map_count, actual_max_map_count);
log_warning (gc)(" limit could lead to a fatal error, due to failure to map memory." );
log_warning_p (gc)(" limit could lead to a fatal error, due to failure to map memory." );
}
}
@@ -564,7 +565,7 @@ ZErrno ZPhysicalMemoryBacking::fallocate_fill_hole(size_t offset, size_t length)
}
// Not supported
log_debug (gc)(" Falling back to fallocate() compatibility mode" );
log_debug_p (gc)(" Falling back to fallocate() compatibility mode" );
z_fallocate_supported = false ;
}
@@ -645,7 +646,7 @@ bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) {
// will fail, since there is a delay between process termination and the
// huge pages owned by that process being returned to the huge page pool
// and made available for new allocations.
log_debug (gc, init)(" Failed to commit memory (%s), retrying" , err.to_string ());
log_debug_p (gc, init)(" Failed to commit memory (%s), retrying" , err.to_string ());
// Wait and retry in one second, in the hope that huge pages will be
// available by then.
@@ -654,7 +655,7 @@ bool ZPhysicalMemoryBacking::commit_inner(size_t offset, size_t length) {
}
// Failed
log_error (gc)(" Failed to commit memory (%s)" , err.to_string ());
log_error_p (gc)(" Failed to commit memory (%s)" , err.to_string ());
return false ;
}