How to Emulate Persistent Memory Using Dynamic Random-access Memory (DRAM)
如何使用动态随机存取存储器(DRAM)模拟持久
介绍
传统的应用程序在两层之间组织数据:内存和存储。新兴的持久存储器技术引入了第三层。这一层可以像易失性存储器一样使用处理器加载和存储指令进行访问,但它会像存储一样在断电时保留其内容。Intel® Optane™ DC持久内存模块是适合此层的高容量非易失性双列直插式内存模块(NVDIM)non-volatile dual in-line memory modules。
如果您是一名软件开发人员,希望开始开发软件或修改应用程序以具有持久内存(PMEM)意识,但您没有这些持久内存模块,则可以使用仿真进行开发。
本教程提供了一种在具有Linux*内核4.3或更高版本的物理或虚拟机(VM)上使用常规动态随机存取存储器(DRAM)设置PMEM仿真的方法。它是在英特尔®;至强®;处理器E5-2699 v4处理器、2.2 GHz、英特尔®;服务器系统R2000WT产品系列平台上的系统上开发和测试的,运行CentOS*7.2和Linux*内核4.5.3。
有关PMEM编程的信息,请访问英特尔®;开发人员专区永久内存网站。在那里,您可以找到有关PMEM编程主题的文章、示例代码、行业演示的链接,以及有关开源持久内存开发工具包(PMDK)的信息。Persistent Memory Development Kit (PMDK)。该工具包包括开发人员工具和一组基于存储网络行业协会(SNIA)NVM编程模型的库。
https://www.snia.org/tech_activities/standards/curr_standards/npm
为什么使用仿真?
在项目的功能开发阶段,您不需要模拟持久内存,但除此之外,当缓存刷新操作必须将数据发送到传统存储设备时,您还需要模拟以避免msync(2)操作的缓慢性能。使用PMEM仿真,您的代码将使用内存缓存刷新指令,就像存在Intel Optane DC持久内存模块时一样。
虚拟化环境中的仿真
如果您将在VM中使用PMEM仿真,请在VM来宾中遵循本文中的说明。主机系统上不需要任何工作。
使用DRAM模拟永久存储器
持久内存的仿真基于DRAM内存,操作系统(OS)将其视为PMEM区域。因为它是一个基于DRAM的仿真,它可能比持久内存更快,并且在机器断电时所有数据都会丢失。下面是我们将遵循的配置步骤的概述。如果您使用的是支持PMEM的Linux发行版,则可以跳过步骤1:
(1)在内核配置中保留PMEM
启用BIOS将标记为e820-type 12的内存视为PMEM;
启用直接访问(DAX);
(2)识别DRAM中的可用区域
(3)使用GRUB文件指定memap内核参数
(4)重新启动时:
PMEM区域将被创建;
内核为PMEM驱动程序提供了这个空间;
Linux将此DRAM区域视为PMEM,并创建PMEM设备(/dev/pmem0、/dev/pem1…);
(5)创建文件系统–已修改ext4和XFS以支持PMEM
(6)使用直接访问(DAX)选项在/dev/pem上装载文件系统
Linux* Kernel Configuration
自4.0版以来,Linux内核中一直支持持久内存设备和仿真,但是,为了更容易配置,建议使用比4.2更新的内核。在内核中,使用文件系统的DAX扩展来创建PMEM感知环境。一些发行版,如Fedora*24和更高版本,内置了DAX/PMEM支持。要了解内核是否支持DAX和PMEM,请使用以下命令:
egrep ‘(DAX|PMEM)’ /boot/config-`uname –r`
命令输出应类似于:
如果您的内核支持DAX和PMEM,您可以跳到本文的“GRUB配置”部分来配置到DRAM的内存映射。如果不支持,请按照下面的步骤修改、构建和安装支持DAX与PMEM的内核。
Enable DAX and PMEM in the Kernel
要配置正确的驱动程序安装,请运行make nconfig并启用驱动程序。根据下面的说明,图1至图5显示了“内核配置”菜单中Intel Optane DC持久内存模块支持的正确设置。
Figure 1: Set up device drivers.
Figure 2: Set up the NVDIMM device.
Figure 3: Set up the file system for Direct Access support.
Figure 4: Set up for Direct Access (DAX) support.
Figure 5: NVDIMM Support property.
处理器类型和功能设置
您还需要启用使用非标准e820类型12标记为受保护内存的处理。内核将把这些区域提供给PMEM驱动程序,用作永久存储。
Figures 6 and 7 show the required change to "Processor type and features" in the Kernel Configuration menu.
Figure 6: Set up the processor to support NVDIMMs.
Figure 7: Enable NON-standard NVDIMMs and ADR protected memory.
Build and Install the Kernel
Now you are ready to build and install your kernel.
# make -jX # where X is the number of cores on the machine
# make modules_install install
GRUB Configuration
接下来,我们将修改引导配置文件,以保留一个内存区域供OS用作永久内存。配置更改是使用GRUB完成的,步骤因Linux发行版而异。
首先,您必须确定要保留的可用物理地址。阅读持久内存Wiki跟踪how_to_choose_the_correct_memp_kernel_parameter_for_pmem_on_your_system以获取此任务的帮助。一旦确定了可用的地址范围,请按照下面的说明进行操作。
how_to_choose_the_correct_memp_kernel_parameter_for_pmem_on_your_system
在为PMEM选择memap内核参数时,您必须注意您试图保留的物理地址代表可用的RAM(usable )。此信息可在e820表中轻松获取,可通过dmesg获取。
下面是一个使用具有20GiB内存的虚拟机的示例设置:
dmesg | grep BIOS-e820
在此输出中,标记为“usable”的区域是为PMEM驱动程序保留的公平游戏,而“reserved”的区域则不是。最后一个可用区域代表了大部分可用空间,因此我们将使用它。
将这些物理地址插入我们的十六进制计算器,该区域开始于0x0000000100000000(4GiB),结束于0x00000053fffff(21GiB)。假设我们想保留16 GiB供PMEM使用。我们可以从4GiB开始保留,而大小为16GiB的保留将在20GiB结束,这仍然在这个可用范围内。该保留的语法如下:
memmap=16G!4G
使用新的内核参数重新启动后,我们还可以通过dmesg看到新的用户定义的e820表(如果您想比较,旧表仍然存在):
dmesg | grep user:
我们可以看到,我们的新持久内存范围确实从4GiB开始,到20GiB结束,与e820表输出中定义的可用内存范围完全重叠。
如果我们加载了pmem驱动程序,我们将看到这个保留内存范围为/dev/pmem0:
fdisk -l /dev/pmem0
您可能需要注意的另一件事是CONFIG_RANDOMIZE_BASE内核配置选项。启用后,这将随机化内核映像解压缩的物理地址和内核映像映射的虚拟地址。目前,这个随机地址的选择与memap内核命令行参数无关。
这意味着内核可以选择将自己放在保留的memmap区域的中间。您可以通过/proc/iomem观察此行为。
以下是关闭CONFIG_RANDOMIZE_BASE的系统的/proc/iomem:
我们感兴趣的是00100000-bffd8fff的“系统RAM”区域和100000000-4ffffff的“持久内存(遗留)”区域。
如果在同一系统上打开CONFIG_RANDOMIZE_BASE,我会得到以下结果:
“系统RAM”区域现在位于我的“持久内存(遗留)”区域的中间,将其一分为二。这将导致以下内核警告:
并且没有创建/dev/pem*设备。
CONFIG_RANDOMIZE_BASE(KASLR)问题应已修复:f28442497b5caf(“x86/boot:Fix KASLR and memmap=collision”)
然而,CONFIG_KSAN目前似乎存在问题。
memmap=nn[KMG]!ss[KMG]
例如,memap=4G!12G在第12和第16 GB之间保留4 GB内存。下面的示例显示了如何在CentOS 7.0 BIOS或基于EFI的机器上编辑GRUB文件并构建配置。
在BIOS机器上构建配置:
grub2-mkconfig -o /boot/grub2/grub.cfg
在EFI机器上构建配置:
grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
图8显示了对GRUB文件的memap更改。请注意,此示例指定了四个内存区域的映射。图9显示了运行grub2mkconfig的输出。
Figure 8: Define PMEM regions in the /etc/default/grub file.
Figure 9: Generate the boot configuration file based on the GRUB template.
Build a DAX-enabled File System
我们过程中的最后一步是为持久设备构建启用DAX的文件系统。为此,我们为每个设备创建一个ext4或xfs文件系统,然后使用DAX选项装载它。在下面的示例中,我们在/dev/pem3上创建了一个ext4文件系统。
mkdir /mnt/pmemdir
mkfs.ext4 /dev/pmem3
mount -o dax /dev/pmem3 /mnt/pmemdir
现在可以在新安装的分区上创建文件,用于创建PMDK池。
How to Emulate Persistent Memory Using Dynamic Random-access Memory...