如何在Linux 6.x内核源码中给交换空间访问插入延迟?
解决Linux内核Swap访问时插入人为延迟的方案
为什么修改do_page_fault()效果不稳定
do_page_fault()处理所有类型的页错误——包括用户态缺页、内核态缺页、文件页缺页等,只有匿名页缺页且需要从Swap换入的场景才是你目标的Swap访问路径。直接在这个函数加延迟会牵连所有页错误场景,无法精准命中Swap访问,自然效果不稳定。
正确的插入位置:Swap换入核心路径
针对6.0.6版本内核,你需要修改Swap换入的专属逻辑函数,精准覆盖Swap读写场景:
swap_readpage():位于mm/swap_state.c,是从Swap设备读取页的核心入口,所有Swap换入操作最终都会调用它。swapin_readahead():同样在mm/swap_state.c,处理Swap预读场景,需要覆盖预读的Swap访问时也要在这里加延迟。
修改示例(以swap_readpage()为例)
- 打开
mm/swap_state.c,找到目标函数并插入延迟:
int swap_readpage(struct page *page) { struct swap_info_struct *sis; swp_entry_t entry = { .val = page_private(page) }; int ret; // 插入100毫秒人为延迟,可按需调整时长 msleep(100); sis = swap_info_get(entry); if (!sis) return -EINVAL; ret = sis->ops->readpage(page); swap_info_put(sis); return ret; }
- 若需要覆盖预读场景,在
swapin_readahead()函数开头同样加入msleep()延迟即可。
验证修改有效性
- 编译新内核并重启系统进入新内核环境。
- 制造Swap压力触发换入:用
stress工具创建大量匿名内存占用:
stress --vm 4 --vm-bytes 8G --vm-hang 0
- 通过
vmstat观察si列(Swap换入统计),同时测试应用响应延迟,确认只有Swap访问时会出现预期延迟。
注意事项
- 内核态只能用内核延迟函数:
msleep()(毫秒级)、udelay()(微秒级)、ndelay()(纳秒级),禁止使用用户态的sleep()。长时间延迟可能触发内核软锁警告,需根据测试需求调整时长。 - 编译前确保安装完整依赖:
build-essential、libncurses-dev、bison、flex、libssl-dev、libelf-dev等工具包。 - 建议用虚拟机测试,避免物理机内核崩溃影响系统稳定性。
内容的提问来源于stack exchange,提问作者Abbas
相关产品推荐
相关产品推荐

