Mon, 15 Sep 2014 10:57:22 +0200
8049536: os::commit_memory on Solaris uses aligment_hint as page size
Reviewed-by: stefank, tschatzl
1.1 --- a/src/os/solaris/vm/os_solaris.cpp Fri Apr 17 01:54:23 2015 -0700 1.2 +++ b/src/os/solaris/vm/os_solaris.cpp Mon Sep 15 10:57:22 2014 +0200 1.3 @@ -2696,29 +2696,30 @@ 1.4 } 1.5 } 1.6 1.7 +size_t os::Solaris::page_size_for_alignment(size_t alignment) { 1.8 + assert(is_size_aligned(alignment, (size_t) vm_page_size()), 1.9 + err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, 1.10 + alignment, (size_t) vm_page_size())); 1.11 + 1.12 + for (int i = 0; _page_sizes[i] != 0; i++) { 1.13 + if (is_size_aligned(alignment, _page_sizes[i])) { 1.14 + return _page_sizes[i]; 1.15 + } 1.16 + } 1.17 + 1.18 + return (size_t) vm_page_size(); 1.19 +} 1.20 + 1.21 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, 1.22 size_t alignment_hint, bool exec) { 1.23 int err = Solaris::commit_memory_impl(addr, bytes, exec); 1.24 - if (err == 0) { 1.25 - if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) { 1.26 - // If the large page size has been set and the VM 1.27 - // is using large pages, use the large page size 1.28 - // if it is smaller than the alignment hint. This is 1.29 - // a case where the VM wants to use a larger alignment size 1.30 - // for its own reasons but still want to use large pages 1.31 - // (which is what matters to setting the mpss range. 1.32 - size_t page_size = 0; 1.33 - if (large_page_size() < alignment_hint) { 1.34 - assert(UseLargePages, "Expected to be here for large page use only"); 1.35 - page_size = large_page_size(); 1.36 - } else { 1.37 - // If the alignment hint is less than the large page 1.38 - // size, the VM wants a particular alignment (thus the hint) 1.39 - // for internal reasons. Try to set the mpss range using 1.40 - // the alignment_hint. 1.41 - page_size = alignment_hint; 1.42 - } 1.43 - // Since this is a hint, ignore any failures. 1.44 + if (err == 0 && UseLargePages && alignment_hint > 0) { 1.45 + assert(is_size_aligned(bytes, alignment_hint), 1.46 + err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint)); 1.47 + 1.48 + // The syscall memcntl requires an exact page size (see man memcntl for details). 1.49 + size_t page_size = page_size_for_alignment(alignment_hint); 1.50 + if (page_size > (size_t) vm_page_size()) { 1.51 (void)Solaris::setup_large_pages(addr, bytes, page_size); 1.52 } 1.53 } 1.54 @@ -3251,7 +3252,22 @@ 1.55 } 1.56 } 1.57 1.58 +bool os::Solaris::is_valid_page_size(size_t bytes) { 1.59 + for (int i = 0; _page_sizes[i] != 0; i++) { 1.60 + if (_page_sizes[i] == bytes) { 1.61 + return true; 1.62 + } 1.63 + } 1.64 + return false; 1.65 +} 1.66 + 1.67 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) { 1.68 + assert(is_valid_page_size(align), err_msg(SIZE_FORMAT " is not a valid page size", align)); 1.69 + assert(is_ptr_aligned((void*) start, align), 1.70 + err_msg(PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align)); 1.71 + assert(is_size_aligned(bytes, align), 1.72 + err_msg(SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align)); 1.73 + 1.74 // Signal to OS that we want large pages for addresses 1.75 // from addr, addr + bytes 1.76 struct memcntl_mha mpss_struct;
2.1 --- a/src/os/solaris/vm/os_solaris.hpp Fri Apr 17 01:54:23 2015 -0700 2.2 +++ b/src/os/solaris/vm/os_solaris.hpp Mon Sep 15 10:57:22 2014 +0200 2.3 @@ -110,6 +110,8 @@ 2.4 static meminfo_func_t _meminfo; 2.5 2.6 // Large Page Support 2.7 + static bool is_valid_page_size(size_t bytes); 2.8 + static size_t page_size_for_alignment(size_t alignment); 2.9 static bool setup_large_pages(caddr_t start, size_t bytes, size_t align); 2.10 2.11 static void init_thread_fpu_state(void);
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/runtime/memory/LargePages/TestLargePageSizeInBytes.java Mon Sep 15 10:57:22 2014 +0200 3.3 @@ -0,0 +1,61 @@ 3.4 +/* 3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/* @test TestLargePageSizeInBytes 3.28 + * @summary Tests that the flag -XX:LargePageSizeInBytes does not cause warnings on Solaris 3.29 + * @bug 8049536 3.30 + * @library /testlibrary 3.31 + * @run driver TestLargePageSizeInBytes 3.32 + */ 3.33 + 3.34 +import com.oracle.java.testlibrary.OutputAnalyzer; 3.35 +import com.oracle.java.testlibrary.Platform; 3.36 +import com.oracle.java.testlibrary.ProcessTools; 3.37 + 3.38 +public class TestLargePageSizeInBytes { 3.39 + private static long M = 1024L * 1024L; 3.40 + private static long G = 1024L * M; 3.41 + 3.42 + public static void main(String[] args) throws Exception { 3.43 + if (!Platform.isSolaris()) { 3.44 + // We only use the syscall mencntl on Solaris 3.45 + return; 3.46 + } 3.47 + 3.48 + testLargePageSizeInBytes(4 * M); 3.49 + testLargePageSizeInBytes(256 * M); 3.50 + testLargePageSizeInBytes(512 * M); 3.51 + testLargePageSizeInBytes(2 * G); 3.52 + } 3.53 + 3.54 + private static void testLargePageSizeInBytes(long size) throws Exception { 3.55 + ProcessBuilder pb = 3.56 + ProcessTools.createJavaProcessBuilder("-XX:+UseLargePages", 3.57 + "-XX:LargePageSizeInBytes=" + size, 3.58 + "-version"); 3.59 + 3.60 + OutputAnalyzer out = new OutputAnalyzer(pb.start()); 3.61 + out.shouldNotContain("Attempt to use MPSS failed."); 3.62 + out.shouldHaveExitValue(0); 3.63 + } 3.64 +}