使用qemu模拟CXL.mem设备

2023-12-01 19:10
文章标签 使用 模拟 设备 mem qemu cxl

本文主要是介绍使用qemu模拟CXL.mem设备,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CXL可以说是自PCIe技术诞生几十年以来最具变革性的新技术了。可以想象有了CXL以后机箱的边界将被彻底打破,服务器互相使用对方的内存,网卡,GPU 。整个机架甚至跨机架的超级资源池化成为可能,云计算也将进入一个新的时代。

当前Intel, AMD 目前最新CPU型号也都已经支持CXL接口,三星也有支持CXL的内存模组提供,但是普及性还是非常低,可能只有极个别的研究人员才能拿到真正的物理设备。作为不那么有实力的普通IT从业者如何才能体验这一最前沿的科技成果呢?使用模拟器便是最方便的选择。

本文包括两部分内容,
1)如何使用qemu搭建CXL模拟环境,列出关键的避坑点。这部分需要一定的软件开发基础。
2)从模拟器里看到的CXL设备什么样,这部分适合大多数IT从业者,看到就是体验到

一、搭建CXL qemu模拟器

搭建模拟环境需要三个软件:1)合适版本的qemu 2)合适版本的linux内核 3)合适版本的ndctl软件。 这里说“合适” 是想说并非随便抓个版本过来就可以使用,因为CXL正在飞速演进,软件生态也在不断迭代中,合适的版本才能配合到一起。

1) 编译qemu, 我使用的qemu代码库在:https://gitlab.com/jic23/qemu/-/tree/cxl-2023-04-19, commit ID: 8eb2a03258 

具体编译过程不是本文重点,这里省略,请大家自行解决。

2)使用qemu启动一个VM,我使用的是 CentOS8.4, 可以自己安装也可以从网上下载安装好了的qcow2文件。同样这个的具体操作步骤省略。

3)编译Linux内核,步骤2把VM起来后我们需要更新其内核。本文测试使用的是6.3.0版本内核,从https://gitee.com/mirrors/linux_old1.git 这个代码库克隆,commit ID: 457391b03803

编译内核时需要使能CXL支持,在.config文件里如下配置:

# grep CXL .config
CONFIG_CXL_BUS=m
CONFIG_CXL_PCI=m
CONFIG_CXL_MEM_RAW_COMMANDS=y
CONFIG_CXL_ACPI=m
CONFIG_CXL_PMEM=m
CONFIG_CXL_MEM=m
CONFIG_CXL_PORT=m
CONFIG_CXL_SUSPEND=y
CONFIG_CXL_REGION=y
CONFIG_CXL_REGION_INVALIDATION_TEST=y
CONFIG_DEV_DAX_CXL=m

4) ndctl工具,使用  https://github.com/pmem/ndctl.git , commit ID: 96bae09

这个工具需要在guest OS里面使用。也需要大家自行编译。

应该说上面这几个过程还是颇有些繁琐,光编译环境就要Host, guest搭两次,笔者也是折腾了好久。为了不影响本文主要目标,保持行文简洁只能忍痛省略。

二、启动qemu

启动qemu时添加CXL.mem设备,这里直接给出启动命令,大家看命令行就知道如何设置

/data/cxl/qemu/build/qemu-system-x86_64  -enable-kvm -cpu host -smp 8 \-machine type=q35,accel=kvm,nvdimm=on,cxl=on   \-drive if=ide,file=./centosx86.qcow2,cache=none  \-m 32G,slots=8,maxmem=64G -vnc :3 \-nic user,hostfwd=tcp::10023-:22 \-net nic,macaddr=12:34:56:78:9a:bc \-net tap,ifname=tap3 \-cdrom /data/CentOS-8.4.2105-x86_64-dvd1.iso \-object memory-backend-file,id=cxl-mem1,share=on,mem-path=/tmp/cxltest.raw,size=256M \
-object memory-backend-file,id=cxl-lsa1,share=on,mem-path=/tmp/lsa.raw,size=256M \
-device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
-device cxl-rp,port=0,bus=cxl.1,id=root_port13,chassis=0,slot=2 \
-device cxl-type3,bus=root_port13,memdev=cxl-mem1,lsa=cxl-lsa1,id=cxl-pmem0 \
-M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G

三、 CXL之初体验

1) 首先我们看系统里cxl设备出现在哪里:

# ls /dev/cxl/
mem0

没错,就是多出了这么个小小的设备文件。

2)再具体一点,使用刚才编译的ndctl工具,最新的版本里面带了一个叫cxl的工具,

还可以再具体一些,# cxl list -v 

# cxl list -v
[{"bus":"root0","provider":"ACPI.CXL","nr_dports":1,"dports":[{"dport":"pci0000:0c","alias":"ACPI0016:00","id":12}],"ports:root0":[{"port":"port1","host":"pci0000:0c","depth":1,"nr_dports":1,"dports":[{"dport":"0000:0c:00.0","id":0}],"endpoints:port1":[{"endpoint":"endpoint2","host":"mem0","depth":2,"memdev":{"memdev":"mem0","pmem_size":268435456,"serial":0,"host":"0000:0d:00.0","partition_info":{"total_size":268435456,"volatile_only_size":0,"persistent_only_size":268435456,"partition_alignment_size":0}
},"decoders:endpoint2":[{"decoder":"decoder2.0","interleave_ways":1,"state":"disabled"},{"decoder":"decoder2.1","interleave_ways":1,"state":"disabled"},{"decoder":"decoder2.2","interleave_ways":1,"state":"disabled"},{"decoder":"decoder2.3","interleave_ways":1,"state":"disabled"}]}],"decoders:port1":[{"decoder":"decoder1.0","interleave_ways":1,"state":"disabled","nr_targets":1,"targets":[{"target":"0000:0c:00.0","position":0,"id":0}]}]}],"decoders:root0":[{"decoder":"decoder0.0","resource":79725330432,"size":4294967296,"interleave_ways":1,"max_available_extent":4294967296,"pmem_capable":true,"volatile_capable":true,"accelmem_capable":true,"nr_targets":1,"targets":[{"target":"pci0000:0c","alias":"ACPI0016:00","position":0,"id":12}]}]}
]

3) 使用这个设备

当前我们模拟出来的是一个CXL接口的pmem设备,像AEP。

# cxl create-region -d decoder0.0 -t pmem -m mem0
{"region":"region0","resource":"0x1290000000","size":"256.00 MiB (268.44 MB)","interleave_ways":1,"interleave_granularity":256,"decode_state":"commit","mappings":[{"position":0,"memdev":"mem0","decoder":"decoder2.0"}]
}
cxl region: cmd_create_region: created 1 region# cxl list
[{"memdevs":[{"memdev":"mem0","pmem_size":268435456,"serial":0,"host":"0000:0d:00.0"}]},{"regions":[{"region":"region0","resource":79725330432,"size":268435456,"interleave_ways":1,"interleave_granularity":256,"decode_state":"commit"}]}
][root@vm3 ~]# ndctl create-namespace
{"dev":"namespace0.0","mode":"fsdax","map":"dev","size":"250.00 MiB (262.14 MB)","uuid":"25fab29a-f4ce-483e-94b4-176c40111f6c","sector_size":512,"align":2097152,"blockdev":"pmem0"
}
[root@vm3 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   50G  0 disk
└─sda1   8:1    0   50G  0 part /
sr0     11:0    1  9.3G  0 rom
pmem0  259:0    0  250M  0 disk

 经过上面这一系列的cxl命令,ndctl命令,lsblk终于看到pmem0设备了,使用过AEP的的朋友对这个设备肯定不陌生,之后就跟AEP的使用方法一样了,格式化文件系统,映射到内存空间 ...,本文不再赘述。

这篇关于使用qemu模拟CXL.mem设备的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/442363

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他