120 _initialized(false) { 121 122 // Create backing file 123 _fd = create_fd(ZFILENAME_HEAP); 124 if (_fd == -1) { 125 return; 126 } 127 128 // Get filesystem statistics 129 struct statfs buf; 130 if (fstatfs(_fd, &buf) == -1) { 131 ZErrno err; 132 log_error(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string()); 133 return; 134 } 135 136 _filesystem = buf.f_type; 137 _block_size = buf.f_bsize; 138 _available = buf.f_bavail * _block_size; 139 140 // Make sure we're on a supported filesystem 141 if (!is_tmpfs() && !is_hugetlbfs()) { 142 log_error(gc)("Backing file must be located on a %s or a %s filesystem", 143 ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS); 144 return; 145 } 146 147 // Make sure the filesystem type matches requested large page type 148 if (ZLargePages::is_transparent() && !is_tmpfs()) { 149 log_error(gc)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem", 150 ZFILESYSTEM_TMPFS); 151 return; 152 } 153 154 if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) { 155 log_error(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel", 156 ZFILESYSTEM_TMPFS); 157 return; 158 } 159 160 if (ZLargePages::is_explicit() && !is_hugetlbfs()) { 161 log_error(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled " 162 "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS); 163 return; 164 } 165 166 if (!ZLargePages::is_explicit() && is_hugetlbfs()) { 167 log_error(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem", 168 ZFILESYSTEM_HUGETLBFS); 169 return; 170 } 171 172 const size_t expected_block_size = is_tmpfs() ? os::vm_page_size() : os::large_page_size(); 173 if (expected_block_size != _block_size) { 174 log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")", 175 is_tmpfs() ? ZFILESYSTEM_TMPFS : ZFILESYSTEM_HUGETLBFS, _block_size, expected_block_size); 176 return; 177 } 178 179 // Successfully initialized 180 _initialized = true; 181 } 182 183 int ZPhysicalMemoryBacking::create_mem_fd(const char* name) const { 184 // Create file name 185 char filename[PATH_MAX]; 186 snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : ""); 187 188 // Create file 189 const int extra_flags = ZLargePages::is_explicit() ? MFD_HUGETLB : 0; 190 const int fd = ZSyscall::memfd_create(filename, MFD_CLOEXEC | extra_flags); 191 if (fd == -1) { 192 ZErrno err; 193 log_debug(gc, init)("Failed to create memfd file (%s)", 194 ((ZLargePages::is_explicit() && err == EINVAL) ? "Hugepages not supported" : err.to_string())); 195 return -1; | 120 _initialized(false) { 121 122 // Create backing file 123 _fd = create_fd(ZFILENAME_HEAP); 124 if (_fd == -1) { 125 return; 126 } 127 128 // Get filesystem statistics 129 struct statfs buf; 130 if (fstatfs(_fd, &buf) == -1) { 131 ZErrno err; 132 log_error(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string()); 133 return; 134 } 135 136 _filesystem = buf.f_type; 137 _block_size = buf.f_bsize; 138 _available = buf.f_bavail * _block_size; 139 140 // Make sure the filesystem type matches requested large page type 141 if (ZLargePages::is_transparent() && !is_tmpfs()) { 142 log_error(gc)("-XX:+UseTransparentHugePages can only be enabled when using a %s filesystem", 143 ZFILESYSTEM_TMPFS); 144 return; 145 } 146 147 if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) { 148 log_error(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel", 149 ZFILESYSTEM_TMPFS); 150 return; 151 } 152 153 if (ZLargePages::is_explicit() && !is_hugetlbfs()) { 154 log_error(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled " 155 "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS); 156 return; 157 } 158 159 if (!ZLargePages::is_explicit() && is_hugetlbfs()) { 160 log_error(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem", 161 ZFILESYSTEM_HUGETLBFS); 162 return; 163 } 164 165 if (ZLargePages::is_explicit() && os::large_page_size() != ZGranuleSize) { 166 log_error(gc)("Incompatible large page size configured " SIZE_FORMAT " (expected " SIZE_FORMAT ")", 167 os::large_page_size(), ZGranuleSize); 168 return; 169 } 170 171 // Make sure the filesystem block size is compatible 172 if (ZGranuleSize % _block_size != 0) { 173 log_error(gc)("Filesystem backing the heap has incompatible block size (" SIZE_FORMAT ")", 174 _block_size); 175 return; 176 } 177 178 if (is_hugetlbfs() && _block_size != os::large_page_size()) { 179 log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")", 180 ZFILESYSTEM_HUGETLBFS, _block_size, os::large_page_size()); 181 return; 182 } 183 184 // Successfully initialized 185 _initialized = true; 186 } 187 188 int ZPhysicalMemoryBacking::create_mem_fd(const char* name) const { 189 // Create file name 190 char filename[PATH_MAX]; 191 snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : ""); 192 193 // Create file 194 const int extra_flags = ZLargePages::is_explicit() ? MFD_HUGETLB : 0; 195 const int fd = ZSyscall::memfd_create(filename, MFD_CLOEXEC | extra_flags); 196 if (fd == -1) { 197 ZErrno err; 198 log_debug(gc, init)("Failed to create memfd file (%s)", 199 ((ZLargePages::is_explicit() && err == EINVAL) ? "Hugepages not supported" : err.to_string())); 200 return -1; |