背景

在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制作启动盘,下载地址,下载第一个即可。
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/abc5da92565eee24f412dc04147329c0.png#pic_center =440x140)
下载后打开,其他选项都默认就好了。
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/6ae0c8a506ca1c1dd54d658af89b2e11.png#pic_center =280x480)

BIOS设置

一般开机在显示电脑品牌时按住F12或者F2,还有少数是Del键可以进入BIOS设置,变成U盘启动。而对于Windows10和11,还可以从系统进入,这样更加方便,图文教程具体步骤如下:搜索框搜索BIOS,点击更改高级启动选项——>点击高级启动下面的立即重新启动——>等待几秒黑屏进入蓝色界面,点击疑难解答——>选择点击高级选项——>选择点击UEFI固件设置——>最后一步点击重启,等待电脑直接进入BIOS界面。

如果看不见启动盘,可能是Secure Boot处于Enable的状态,改为Disable看看。

如果上面两种方式都没有成功,那么可以电话咨询该品牌的售后,他们会热心且顺畅的教你。

系统分区

安装建议选择中文,之后不用配置键盘啥的。建议选择最小安装就够了。记得安装时不要联网,会很慢很慢。磁盘至少需要50G容量!

到了分区选择的时候,如果是整个系统重置直接选第一个,最简单了:
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/7d67f78248241c8b8707890ba139ed7a.png#pic_center =280x180)
如果是双系统或者虚拟机以及其他,一个用户自己用,建议分区尽量少,如果有多余的50G容量,请留出空白磁盘不急着分区。目的是遇见提示文件系统空间不足而编译失败, 则会有一行的”已用%”为100%(或者百分比最大且容量最大的那一行, 应该是/dev/sda编号的某一个)。记住这一行的名字,之后去磁盘扩容。

当要是出现Out of memory的黑屏或者屏幕卡住没办法操作的情况:
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/409704d7845ebeaf1944f2c4ae9887a3.jpeg#pic_center =280x180)

不用强制重启!这里给出安全重启的方法:同时按住Ctrl+Alt不要放,再依次按下:SysRq(有的是PrtSc)、R、E、I、S、U、B键,之后系统会安全重启。

安装QQ(方便传文件,需要的话)

  1. 在Firefox内搜索QQ,在QQ安装的网页滑到最底端,就会有Linux版本安装入口。
  2. 选择X64、deb格式,下载。
  3. 下载完成后进入文件所在位置输入命令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等。

换源

依然是使用清华源选择对应版本就行,网页上有教学怎么换。
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/d5574d3e1aa82b916ea9aaaa11f65bb7.png#pic_center =440x140)
换完后使用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会显示详细信息。
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/c9512cd80fb32330ebb17da74a61f3e9.jpeg#pic_center =440x500)

下载源码

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

![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/4ca6bb0fbb2637374c3d89a6905f47a4.png#pic_center =480x140)
接着更新 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行组成了内核的命名
![](https://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/de58da9fd25d33fbd438adb82701efd2.png#pic_center =440x170)
在.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://images.weserv.nl/?url=https://i-blog.csdnimg.cn/blog_migrate/1beecfa359ad08d6e9fb89e7b8c4c6d7.png#pic_center =540x270)

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)

文章作者: 易百分
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 易百分 !
  目录