背景
在Ubuntu18.04和Ubuntu20.04编译Multi-clock步骤(从安装系统开始适合入门);并对Multi-clock的部分参数做敏感性实验;以及nimble、tiering-0.8、 HeMem、autotiering这些顶会开源内核的编译安装注意点。
Multi-clock内核来自于这篇论文
为什么不用最新的Ubuntu22.04?
因为在Ubuntu22.04上编译该内核出现的报错笔者没有解决。当时解决方案是需要在.config文件添加CONFIG_PREEMPT=y,和CPU抢占有关,导致这个报错解决后又出现下一个报错,并且指向某个内核的文件需要修改,就没有继续了。
也很不建议用Ubuntu18.04,因为如果用傲腾AD模式这个版本对应的ndctl和daxctl的版本默认是达不到66及以上的。
不过注意,论文里用的是CentOS7,如果用deb系列,那就Ubuntu20.04最方便。
系统安装
下载镜像
直接去官网下载速度很慢,下载过阿里云的镜像但是也遇到问题了,最保险且快速的镜像下载是清华大学开源软件镜像站页面下滑找到u开头的发布版本。
点进去后选择桌面版镜像
制作启动盘
使用rufus制作启动盘,下载地址,下载第一个即可。

下载后打开,其他选项都默认就好了。

BIOS设置
一般开机在显示电脑品牌时按住F12或者F2,还有少数是Del键可以进入BIOS设置,变成U盘启动。而对于Windows10和11,还可以从系统进入,这样更加方便,图文教程具体步骤如下:搜索框搜索BIOS,点击更改高级启动选项——>点击高级启动下面的立即重新启动——>等待几秒黑屏进入蓝色界面,点击疑难解答——>选择点击高级选项——>选择点击UEFI固件设置——>最后一步点击重启,等待电脑直接进入BIOS界面。
如果看不见启动盘,可能是Secure Boot处于Enable的状态,改为Disable看看。
如果上面两种方式都没有成功,那么可以电话咨询该品牌的售后,他们会热心且顺畅的教你。
系统分区
安装建议选择中文,之后不用配置键盘啥的。建议选择最小安装就够了。记得安装时不要联网,会很慢很慢。磁盘至少需要50G容量!
到了分区选择的时候,如果是整个系统重置直接选第一个,最简单了:

如果是双系统或者虚拟机以及其他,一个用户自己用,建议分区尽量少,如果有多余的50G容量,请留出空白磁盘不急着分区。目的是遇见提示文件系统空间不足而编译失败, 则会有一行的”已用%”为100%(或者百分比最大且容量最大的那一行, 应该是/dev/sda编号的某一个)。记住这一行的名字,之后去磁盘扩容。
当要是出现Out of memory的黑屏或者屏幕卡住没办法操作的情况:

不用强制重启!这里给出安全重启的方法:同时按住Ctrl+Alt不要放,再依次按下:SysRq(有的是PrtSc)、R、E、I、S、U、B键,之后系统会安全重启。
安装QQ(方便传文件,需要的话)
- 在Firefox内搜索QQ,在QQ安装的网页滑到最底端,就会有Linux版本安装入口。
- 选择X64、deb格式,下载。
- 下载完成后进入文件所在位置输入命令
sudo dpkg -i linuxqq_2.0.0-b2-1089_amd64.deb
注意大家版本不同,可以输入linuxqq后按Tab键补全。
ARM64是ARM中64位体系结构,ARM属于精简指令集体系,汇编指令比较简单。x64是x86系列中的64位体系,是x86_64(Intel设计)和AMD64(AMD设计)的简称。x86属于复杂指令集体系,汇编指令较多。属于两种不同的体系。
rpm包主要用于redhat及分支如redhat,centos,Fedora等;而deb包主要用于debian及分支如debian,ubuntu等。
换源
依然是使用清华源选择对应版本就行,网页上有教学怎么换。

换完后使用sudo apt-get update
更新
安装分区管理工具gparted
sudo apt-get install gparted
sudo gparted //启动工具
可以拖动上边的的条形框或者输入新大小来扩展磁盘大小
内核编译相关依赖下载
这是内核编译通用依赖
sudo apt-get install make gcc g++ flex bison libncurses-dev build-essential kernel-package libssl-dev libc6-dev bin86 qttools5-dev libelf-dev -y
在readme文件上还有
Install required packages
前者在Ubuntu19及以后的版本都能安装,而之前的版本需要自己编译。后者旧版在添加PPA源之后能安装。
Ubuntu20.04
相比较而言这个版本安装要省事很多,直接输入命令:
sudo apt install ipmctl
sudo apt install ndctl daxctl
Ubuntu18.04
需要参考官方链接在 Linux 上从源代码构建和安装 IPMCTL网页下滑还有一些常见错误的处理方案。
安装所需实用程序
sudo apt update
sudo apt install wget git cmake pkg-config autoconf doxygen libtool build-essential
安装libsafec-devel
然后添加一个额外的ppa,相当于添加了一个只包括libsafec的公网库,否则会出现说找不到的报错(如果该repository中没有该package,则会抛出Error. E: Unable to locate package)。
sudo add-apt-repository ppa:jhli/libsafec
sudo apt update
sudo apt install libsafec-dev libsafec-3.5.3
Personal Package Archive, 意思是个人包档案。PPA可以提供新版本的软件以及在Linux官方库中没有的软件。PPA就是一种repository,对于Linux系统来说,Repository就是个文件仓库,包含了各个软件的信息,例如:版本号,校验码(checksum)分为以下四种组成部分:
- Main: 标准支持的免费和开源的软件
- Universe: 社区维护的免费和开源的软件
- Restricted: 对各个设备的专有驱动
- Multiverse: 受限于版权或法律条目的软
对于Ubuntu来说,只需要保存这条链接(存放在/etc/apt/source.list中),就能够找到所有属于该repository的软件。对于用户来说,只需将目标软件的PPA repository添加到sources.list中,更新repository列表后便可以找到和安装。有人得到了该软件的源码,在源码上制作PPA。
使用PPA并不会修改原有的sources.list文件,而是在/etc/apt/sources.d目录下创建两个文件。删除PPA:在Settings > Software & Updates > Other Software中可以看到,选中的PPA链接。若取消选中,/etc/apt/sources.list.d则会注释该条目。若选择Remove,/etc/apt/sources.list.d中则会删除该条目。
安装libndctl-devel
下一个依赖安装倒是顺利sudo apt install libndctl-dev
安装ruby-asciidoctor
之后安装又会出现报错,但是连续两次报错,就连续两次输入报错中推荐安装的命令即可以成功。
sudo apt install ruby
sudo gem install asciidoctor asciidoctor-pdf --pre
Build&Install
依赖都装好后开始编译和安装
cd ~
wget https://github.com/intel/ipmctl/archive/refs/tags/v02.00.00.3885.zip
unzip v02.00.00.3885.zip
cd ipmctl-02.00.00.3885/
mkdir output && cd output
cmake -DRELEASE=ON -DCMAKE_INSTALL_PREFIX=/ ..
make -j all
sudo make install
最后验证一下安装成功了没,输入ipmctl
会显示详细信息。

下载源码
wget https://github.com/sylab/multi-clock/archive/refs/heads/main.zip
unzip main.zip
cd multi-clock/src //进入源码的文件,编译需要先找到Kconfig文件
修改源码
这个main下载后,我有遇到报错,包括但不限于如下的报错:
我的解决方式是在mm/vmscan.c
文件中加入一行代码
内核编译
开启内核配置选项
一般采用make menuconfig
,个人觉得这个页面太难找了,还是qt的界面方便一些。
make xconfig
按照readme上的Enable Multi-Clock for Tiered Memory System
to compile the MULTI-CLOCK kernel.
Following are the other required configurations need to be eanbled for MULTI-CLOCK:
allow for memory hot-add
//已默认开启,但可以检查一下Device memory (pmem, HMM, etc...) hotplug support
//已默认开启,但可以检查一下NVDIMM (Non-Volatile Memory Device) Support --->
NVDIMM DAX: Raw access to persistent memory
//已默认开启,但可以检查一下
然后是配置PM热插拔要用的,不是选Y(打勾)是点(选M)
Device Drivers --->
-\*- DAX: direct access to differentiated memory --->
<M> Device DAX: direct access mapping device
<M> PMEM DAX: direct access to persistent memory
<M> KMEM DAX: volatile-use of persistent memory
< > PMEM DAX: support the deprecated /sys/class/dax interface
使用Ctrl+F可以搜索,但是只限于搜索一个单词,不过足够定位选项了,下面用图片展示这些选项的位置:
配置选项都开启完后,点击左上角file>save>quit.
修改内核配置文件
上一步操作后会生成一个.config文件,当内核编译发生报错时,一般会到这个文件里做修改。
在编译前都会做的修改有一个:将CONFIG_SYSTEM_TRUSTED_KEYS的内容变为空。(否则后面会报错的)
gedit .config
然后用Ctrl+F搜索CONFIG_SYSTEM_TRUSTED_KEYS,改掉,保存。
如果编译时遇到报错:Makefile:988: recipe for target ‘certs’ failed,还需要在这个文件里改,将这个参数关闭掉CONFIG_MODULE_SIG=n
注意每次报错后重新开始内核编译都需要:
sudo make mrproper
sudo make clean
然后从make xconfig
这一步重来!
编译内核
这里j几是几个线程同时编译,后面数字是CPU核数的整数倍就可,这样速度会快很多。
make -j20
安装内核
sudo make modules_install //这里出现报错也是需要重来
sudo make install //将自动修改GRUB配置文件
如果用make modules_install执行时,报错如下的话
can't read modules.order: No such file or directory Makefile:xxxx: recipe for target '_modinst_' failed
make: *** [_modinst_] Error 1
解决办法:将make 命令换用 make V=1 all
执行。
更换系统内核
使用ls -l /lib/modules/
命令,可以看到5.3.1-multiclock内核已经装好了。
GRUB 是一个用于加载和管理系统启动的完整程序。它是 Linux 发行版中最常见的引导程序bootloader。引导程序是计算机启动时运行的第一个软件。它加载操作系统的内核,然后再由内核初始化操作系统的其他部分(包括 Shell、显示管理器、桌面环境 等等)。
sudo gedit /etc/default/grub
在文件末尾添加:
GRUB_SAVEDEFAULT=true
GRUB_DEFAULT=saved
注释并且修改:
# GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=30

接着更新 grub 配置:sudo update-grub
重启系统:sudo reboot
在开机之前的 grub 界面中,选择 Advantages for ubuntu (ubuntu高级设置)选项,接着选择自己想要的内核版本进入便可。uname -r
查看系统内核版本。
如果要长期使用这个内核,那就需要注释掉 GRUB_TIMEOUT=30 这一段代码,设置 GRUB_TIMEOUT_STYLE 值为 hidden,不然下次开机还会弹出 grub 界面,最后更新一下配置sudo update-grub
敏感性实验
LRU缓存空间调整
页面会在active和inactice链表中来回移动,如果每次移动都进行操作,那就意味着要获取node节点的自旋锁,竞争非常大,因此引入LRU缓存。就是积累一定数量的页面后再操作。LRU缓存默认批处理页面数为15。新页面加入LRU链表主要通过lru_cache_add
函数,当lru缓存满了之后,就通过__pagevec_lru_add
去实际将页面放入对应lru链表。内核线程kswapd
会周期性地把active list中符合条件的页面移到inactive list中,这项转移工作是由refill_inactive_zone()
完成的。
src/include/linux/pagevec.h/ #define PAGEVEC_SIZE 15
当修改改了一个新的内核,需要去取个名字区别开时,有两处地方可以改名字。
在src文件夹里的Makefile文件如图2-5行组成了内核的命名

在.config文件里修改的CONFIG_LOCALVERSION
内容会成为在Makefile文件里修改的名字的后缀,就是添加在那个名字后面
进程扫描时间间隔
https://cloud.tencent.com/developer/article/1725931 这篇讲解了内核时间管理相关的内容。
周期性事件是由系统的系统定时器驱动的,内核必须在硬件定时器的帮助下才能计算和管理时间。在i386平台上,目前采用的HZ值是1000。不同的体系结构其HZ值是不一样的,比如arm就采用100。如果在驱动中要使用系统的中断频率,直接使用HZ,而不要用100或1000.一个HZ被认为1s.
等待队列实际上就是一个进程链表,链表中包含了等待某个特定事件的所有进程。使用等待队列也可以实现长延迟。在延迟期间,当前进程在等待队列中睡眠。休眠也是基于等待队列实现的,wait_event系列函数,wake_up_interruptible这个是kswap线程的,和wait_event_interruptible一起用于休眠。
要想把进程加入等待队列,驱动首先要在模块中声明一个等待队列头,并将它初始化。在作者修改的代码中可以找到动态初始化:
wait_queue_head_t kpromoted_wait; //这句是添加到NUMA node结构体里的。
#ifdef CONFIG_MULTICLOCK
init_waitqueue_head(&pgdat->kpromoted_wait); //在page_alloc文件中
#endif
http://blog.chinaunix.net/uid-7332782-id-3217821.html 在这篇博客里提到:
prepare_to_wait()和finish_wait()并不是进程睡眠的地方,进程睡眠的地方是schedule()。prepare_to_wait()只是进行一些链表的操作,以确保自己在等待队列中。进程在确信自己已经在队列中后,再次检查条件,这里如果不检查,可能条件已经满足,直接去睡眠的话,可能再也没有人来唤醒它了。

https://blog.csdn.net/u013910383/article/details/121366819 schedule_timeout
函数分析将当前task调度出cpu,并根据传入的timeout决定何时重新调度。所以对进程扫描时间间隔的测试要修改的参数就是几倍HZ了。我们设定将时间间隔改为100ms(0.1)、250ms(0.25)、 500ms(0.5)、1s、 5s(5)和60s(60),并在这些版本中分别运行YCSB的工作负载A。
Nimble的编译安装
每次报错后重新开始内核编译都需要:
sudo make mrproper
sudo make clean
然后从sudo make xconfig
这一步重来!
nimble的内核竟然在第一步报错:没有规则可制作目标scripts/Makefile.lib
。去查看后确实对比multi-clock的内核编译文件,少了这一个,而且静态分层那个内核也少了。但是由于没有添加新的文件,只是在修改原有文件,因此搬过去用也没问题。
让我们看看这个文件是干啥的:如果说 Makefile.build 负责执行 make 的编译过程,而 Makefile.lib 则决定了哪些文件需要编译,哪些目录需要递归进入。http://cxd2014.github.io/2015/11/11/Linux-Makefile/ 一篇不错的解析
从之后的编译情况来看,Makefile.modbuiltin
这个文件也是没有的……也要提前移过去。经过比较之后,包括Makefile.lib和以下这4个文件都是需要移过去的。
之后就是参考readme来配置.config文件了。
Enable Enable Nimble Page Selection for Tiered Memory System
to compile the MULTI-CLOCK kernel.(搜索nimble即可)
Following are the other required configurations need to be eanbled for MULTI-CLOCK:
allow for memory hot-add
Device memory (pmem, HMM, etc...) hotplug support
NVDIMM (Non-Volatile Memory Device) Support --->
(搜索NVDIMM即可)NVDIMM DAX: Raw access to persistent memory
DAX: direct access to differentiated memory --->
(搜索pmem即可)Device DAX: direct access mapping device
PMEM DAX: direct access to persistent memory
KMEM DAX: volatile-use of persistent memory
因为第1、2个选项没有搜索到,所以下面给出具体位置(但其实本来就是打勾的)
sudo gedit .config
然后用Ctrl+F搜索CONFIG_SYSTEM_TRUSTED_KEYS,改掉,保存。
sudo make -j8
sudo make modules_install
sudo make install
仍然有报错,应该是和multi-clock一样的原因,在mm/vmscan.c
文件中加入一行代码。
Kernel: arch/x86/boot/bzImage is ready (#1)
ERROR: "set_pmem_node" [drivers/dax/kmem.ko] undefined!
scripts/Makefile.modpost:103: recipe for target 'modules-modpost' failed
make[1]: *** [modules-modpost] Error 1
Makefile:1301: recipe for target 'modules' failed
make: *** [modules] Error 2
Tiering-0.8编译安装
https://git.kernel.org/pub/scm/linux/kernel/git/vishal/tiering.git/
Updates in tiering-0.8:
- Rebased on v5.15
- 删除cgroup v1支持,我们将在未来的版本中切换到cgroup v2支持。如果您需要cgroup v1支持,请使用v0.72。
- 如果超过阈值的页面太少,则更快地提高热阈值
- 如果检测到工作负载更改,则重置热阈值
- Batch migrate_pages()以减少TLB击落IPI
- 如果刚刚降级的页面是热的,则支持降低热阈值
- 支持异步提升页面
- 支持提前唤醒kswapd,使promotion更加顺利
- 添加更多sysctl旋钮,用于试验新功能
- 更改接口以启用MPOL_PREFERRED_MANY的NUMA平衡
Ensure the following:
CONFIG_DEV_DAX_KMEM=m
CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n
CONFIG_NUMA_BALANCING=y
3. Post boot setup
==================
a. Enable cold page demotion after the device-dax instances are
onlined to start migrating “cold” pages from DRAM to PMEM.
# echo 1 > /sys/kernel/mm/numa/demotion_enabled
b. Enable 'NUMA balancing' for promotion
# echo 2 > /proc/sys/kernel/numa_balancing
# echo 30 > /proc/sys/kernel/numa_balancing_rate_limit_mbps
c. Optional: enable waking up kswapd earlier to make promotion more smooth
# echo 1 > /proc/sys/kernel/numa_balancing_wake_up_kswapd_early
d. Optional: enable decreasing hot threshold if the pages just demoted are hot
# echo 1 > /proc/sys/kernel/numa_balancing_scan_demoted
# echo 16 > /proc/sys/kernel/numa_balancing_demoted_threshold
4. Promotion/demotion statistics
================================
The number of promoted pages can be checked by the following counters in
/proc/vmstat or /sys/devices/system/node/node[n]/vmstat:
pgpromote_success
The number of pages demoted can be checked by the following counters:
pgdemote_kswapd
pgdemote_direct
The page number of failure in promotion could be checked by the
following counters:
pgmigrate_fail_dst_node_fail
pgmigrate_fail_numa_isolate_fail
pgmigrate_fail_nomem_fail
pgmigrate_fail_refcount_fail
HeMem编译和安装
https://bitbucket.org/ajaustin/hemem/src/sosp-submission/
Autotiering安装和编译
但是之前有遇到很多报错,包括在22的ubuntu和18的虚拟机上,问题会比较递归的发生,由于最后还是存在无法解决的问题,就不放报错了。总之最后实践下来,在ubuntu18和可以支持pm的物理机上,是没有报错直接可以安装的。
CONFIG_PAGE_BALANCING=y
CONFIG_PAGE_BALANCING_DEBUG=y # (optional)
CONFIG_PAGE_FAULT_PROFILE=y # (optioanl)