--- old/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp 2020-02-19 09:04:35.041524037 +0100 +++ new/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp 2020-02-19 09:04:34.708517305 +0100 @@ -137,16 +137,12 @@ _block_size = buf.f_bsize; _available = buf.f_bavail * _block_size; - // Make sure we're on a supported filesystem - if (!is_tmpfs() && !is_hugetlbfs()) { - log_error(gc)("Backing file must be located on a %s or a %s filesystem", - ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS); - return; - } + log_info(gc, init)("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 enable when using a %s filesystem", + log_error(gc)("-XX:+UseTransparentHugePages can only be enabled when using a %s filesystem", ZFILESYSTEM_TMPFS); return; } @@ -169,10 +165,22 @@ return; } - const size_t expected_block_size = is_tmpfs() ? os::vm_page_size() : os::large_page_size(); - if (expected_block_size != _block_size) { + 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); + 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); + return; + } + + if (is_hugetlbfs() && _block_size != ZGranuleSize) { log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")", - is_tmpfs() ? ZFILESYSTEM_TMPFS : ZFILESYSTEM_HUGETLBFS, _block_size, expected_block_size); + ZFILESYSTEM_HUGETLBFS, _block_size, ZGranuleSize); return; } @@ -195,7 +203,7 @@ return -1; } - log_info(gc, init)("Heap backed by file: /memfd:%s", filename); + log_info(gc, init)("Backing File: /memfd:%s", filename); return fd; } @@ -231,7 +239,7 @@ return -1; } - log_info(gc, init)("Heap backed by file: %s/#" UINT64_FORMAT, mountpoint.get(), (uint64_t)stat_buf.st_ino); + log_info(gc, init)("Backing File: %s/#" UINT64_FORMAT, mountpoint.get(), (uint64_t)stat_buf.st_ino); return fd_anon; } @@ -257,7 +265,7 @@ return -1; } - log_info(gc, init)("Heap backed by file: %s", filename); + log_info(gc, init)("Backing File: %s", filename); return fd; } --- /dev/null 2020-01-07 09:26:22.747784373 +0100 +++ new/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java 2020-02-19 09:04:35.160526442 +0100 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, 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 gc.z; + +/* + * @test TestAllocateHeapAt + * @requires vm.gc.Z & os.family == "linux" & !vm.graal.enabled + * @summary Test ZGC with -XX:AllocateHeapAt + * @library /test/lib + * @run main/othervm gc.z.TestAllocateHeapAt . true + * @run main/othervm gc.z.TestAllocateHeapAt non-existing-directory false + */ + +import jdk.test.lib.process.ProcessTools; + +public class TestAllocateHeapAt { + public static void main(String[] args) throws Exception { + final String directory = args[0]; + final boolean exists = Boolean.parseBoolean(args[1]); + final String backingFile = "Backing File: " + directory; + final String failedToCreateFile = "Failed to create file " + directory; + + ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(new String[] { + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseZGC", + "-Xlog:gc*", + "-Xms32M", + "-Xmx32M", + "-XX:AllocateHeapAt=" + directory, + "-version" })) + .shouldContain(exists ? backingFile : failedToCreateFile) + .shouldNotContain(exists ? failedToCreateFile : backingFile) + .shouldHaveExitValue(exists ? 0 : 1); + } +}