Path: blob/master/test/jdk/java/nio/MappedByteBuffer/PmemTest.java
41152 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* This test is manually run because it requires an NVRAM device to be25* mapped as DAX file system or, at least, to be simulated by a26* volatile RAM mapped file system. Also, on AArch64 it requires an27* ARMV8.2 CPU which implements the dc CVAP instruction (CPU feature28* dcpop) and an OS that makes it available from user space.29*30* If the test runs on such a host without throwing an exception then31* that confirms that NVRAM-backed byte buffers can be allocated,32* updated and forced via cache line writeback.33*/3435/*36* How to run this test:37*38* Ideally this test should be run on a x86_64/amd64 or aarch64 host39* fitted with an NVRAM memory device. The NVRAM should appear as40* /dev/pmem0 or some equivalent DAX file device. The file device41* should be mounted at /mnt/pmem with a directory tmp created42* directly under that mount point with a+rwx access.43*44* It is possible to run the test on x86_64 using a volatile RAM45* backed device to simulate NVRAM, even though this does not provide46* any guarantee of persistence of data across program runs. For the47* latter case the following instructions explain how to set up the48* simulated NVRAM device.49*50* https://developers.redhat.com/blog/2016/12/05/configuring-and-using-persistent-memory-rhel-7-3/51* https://nvdimm.wiki.kernel.org/52* TL;DR: add "memmap=1G!4G" to /etc/default/grub, eg. GRUB_CMDLINE_LINUX="memmap=1G!4G"53* then ("sudo" may required)54* for RHEL(BIOS-based): grub2-mkconfig -o /boot/grub2/grub.cfg55* for RHEL(UEFI-based): grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg56* for Ubuntu: update-grub257* finally reboot58* after the host been rebooted, a new /dev/pmem{N} device should exist,59* naming conversion starts at /dev/pmem060*61* Prepare test directory follow below commands, "sudo" may required62* (if ndctl or mkfs.xfs not exist, install ndctl or xfsprogs package first)63* (for RHEL8, when call mkfs.xfs, specify the -m reflink=0 option to disable reflink feature)64*65* ndctl create-namespace -f -e namespace0.0 -m memory -M mem66* mkdir /mnt/pmem67* mkfs.xfs -f /dev/pmem0; mount -o dax /dev/pmem0 /mnt/pmem/68* mkdir /mnt/pmem/test; chmod a+rwx /mnt/pmem/test69*70* Now run the test program71*72* java PmemTest73*74* or75*76* make test TEST=jdk/java/nio/MappedByteBuffer/PmemTest.java77*/7879/* @test80* @summary Testing NVRAM mapped byte buffer support81* @run main/manual PmemTest82* @requires (os.family == "linux")83* @requires ((os.arch == "x86_64")|(os.arch == "amd64")|(os.arch == "aarch64")|(os.arch == "ppc64le"))84*/8586import java.io.File;87import java.nio.MappedByteBuffer;88import java.nio.channels.FileChannel;89import java.nio.file.Files;90import java.nio.file.Path;91import java.nio.file.StandardOpenOption;92import java.util.EnumSet;93import java.util.List;94import jdk.nio.mapmode.ExtendedMapMode;9596import java.lang.management.ManagementFactory;97import java.lang.management.BufferPoolMXBean;9899public class PmemTest {100101public static final int K = 1024;102public static final int NUM_KBS = 16;103104public static void main(String[] args) throws Exception {105106System.out.println("test");107108String dir = "/tmp"; // mapSync should fail109dir = "/mnt/pmem/test"; // mapSync should work, since fs mount is -o dax110111Path path = new File(dir, "pmemtest").toPath();112113FileChannel fileChannel = (FileChannel) Files114.newByteChannel(path, EnumSet.of(115StandardOpenOption.READ,116StandardOpenOption.WRITE,117StandardOpenOption.CREATE));118119MappedByteBuffer mappedByteBuffer = fileChannel.map(ExtendedMapMode.READ_WRITE_SYNC, 0, NUM_KBS * K);120121122dumpBufferPoolBeans();123124// for (int loops = 0; loops < 1000; loops++) {125for (int loops = 0; loops < 100; loops++) {126int base = K * (loops % NUM_KBS);127for (int i = 0; i < K ; i++) {128for (int j = 0; j < K ;j++) {129testBuffer(mappedByteBuffer, base, (i << 3) + j);130commitBuffer(mappedByteBuffer, base);131}132}133}134dumpBufferPoolBeans();135}136137public static void testBuffer(MappedByteBuffer mappedByteBuffer, int base, int start) {138for (int k = 0; k < 8; k++) {139int idx = (start + k) % K;140byte z = mappedByteBuffer.get(base + idx);141z++;142mappedByteBuffer.put(base + idx, z);143}144}145146public static void commitBuffer(MappedByteBuffer mappedByteBuffer, int base)147{148mappedByteBuffer.force(base, K);149}150151public static void dumpBufferPoolBeans()152{153List<BufferPoolMXBean> beansList = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);154for (BufferPoolMXBean bean : beansList) {155System.out.println("BufferPoolMXBean {" +156"\n\tname: " + bean.getName() +157"\n\tcount: " + bean.getCount() +158"\n\ttotalCapacity: " + bean.getTotalCapacity() +159"\n\tmemoryUsed: " + bean.getMemoryUsed() +160"\n}");161}162}163}164165166