目录
UFFD With PageFault
通过实践快速理解 UFFD
Userfaultfd(UFFD) 原理
Userfaultfd(UFFD) 数据逻辑
UFFD 应用与落地
UFFD 用户空间监听匿名内存缺页场景
UFFD 用户空间监听虚拟内存 FORK 场景
UFFD 用户空间监听虚拟内存改动场景
UFFD 用户空间监听虚拟内存释放场景
UFFD 用户空间监听 Drop PAGECACHE 场景
UFFD 用户空间监听 HugeTLB 内存缺页场景
UFFD 用户空间监听共享内存缺页场景
UFFD 用户空间监听写保护场景
UFFD 用户空间监听缺页与 ZERO PAGE 场景
Userfaultfd(UFFD) 原理
Userfaultfd(UFFD) 是 Linux 中的一个高级机制,用于处理用户空间虚拟内存缺页。其提供了一种方法,使得用户空间的应用程序能够更细粒度地控制对内存访问. UFFD 不仅仅可以介入用户空间的虚拟内存缺页,而且还可以检测虚拟内存的内存行为,包括: UNMAP、FORK、REMAP 和 REMOVE 等,另外 UFFD 不仅可以检测匿名内存,还可以检测共享内存和 HugeTLB 内存. UFFD 的应用场景也很丰富:
- 内存过载: 在内存敏感的系统或应用程序中,UFFD 可以用来实现按需分页(On-Demand),即只有在实际需要时才加载或分配内存页面
- 迁移和复制: 在虚拟化环境中,UFFD 可以帮助实现实时迁移,即在不停机的情况下将虚拟机从一个物理主机迁移到另一个
- 零拷贝: 在需要大量数据处理的应用程序中,UFFD 可以减少不必要的数据复制,提高性能
- 故障模拟: 对于需要高可靠性的系统,UFFD 可以用来模拟内存故障,帮助开发人员测试和改进错误处理代码
Userfault(UFFD) 工作原理可以精简如上图,当需要监听进程某块虚拟内存行为时,先创建一个 UFFD 对象文件,该文件提供了 IOCTL 接口用于与用户交互,当用户进程访问虚拟内存发生缺页时,UFFD 会在缺页处理函数的路径上放置相应的处理逻辑,UFFD 会在某个阶段接管缺页异常处理函数,然后通过 POLL 通知用户空间,用户空间收到 POLL 通知之后在通过 IOCTL 与 UFFD 对象进行交互以此达到控制内存过程的目的. UFFD 工作步骤如下:
- 创建 UFFD 对象: 应用程序通过调用 userfaultfd 系统调用创建一个新的 UFFD 文件描述符
- 配置检测内存行为: 使用 ioctl 来配置 UFFD 对象,可以设置如何处理页面错误等参数
- 注册检测范围: 应用程序必须使用 ioctl 系统调用注册它希望接收错误通知的内存范围
- 事件通知: 当在已注册的内存区域中发生页面错误时(或某些内存行为时),内核不会立即处理该错误,而是通过 userfaultfd 文件描述符将错误通知给用户空间的应用程序
- 事件响应: 应用程序可以读取 userfaultfd 文件描述符来获取有关页面错误的信息,然后决定如何处理。例如它可以从备份存储加载数据、从其他服务器获取数据、或者只是分配一个新页面
- 解决事件: 一旦应用程序准备好数据,它会使用 ioctl 系统调用通知内核页面已就绪,然后内核会完成页面错误的处理