欢迎光临散文网 会员登陆 & 注册

详细讲解Linux内存管理之RMAP

2022-12-13 15:06 作者:补给站Linux内核  | 我要投稿


说明:

  1. Kernel版本:4.14

  2. ARM64处理器,Contex-A53,双核

  3. 使用工具:Source Insight 3.5, Visio

1. 概述

RMAP反向映射是一种物理地址反向映射虚拟地址的方法。

  • 映射 页表用于虚拟地址到物理地址映射,其中的PTE页表项记录了映射关系,同时struct page结构体中的mapcount字段保存了有多少PTE页表项映射了该物理页。

  • 反向映射 当某个物理地址要进行回收或迁移时,此时需要去找到有多少虚拟地址射在该物理地址,并断开映射处理。在没有反向映射的机制时,需要去遍历进程的页表,这个效率显然是很低下的。反向映射可以找到虚拟地址空间VMA,并仅从VMA使用的用户页表中取消映射,可以快速解决这个问题。


反向映射的典型应用场景:

  1. kswapd进行页面回收时,需要断开所有映射了该匿名页面的PTE表项;

  2. 页面迁移时,需要断开所有映射了该匿名页面的PTE表项;

【文章福利】小编推荐自己的Linux内核技术交流群:【749907784】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)     


2. 数据结构

反向映射有三个关键的结构体:

  1. struct vm_area_struct,简称VMA;VMA我们在之前的文章中介绍过,用于描述进程地址空间中的一段区域。与反向映射相关的字段如下:

2.struct anon_vma,简称AV;AV结构用于管理匿名类型VMAs,当有匿名页需要unmap处理时,可以先找到AV,然后再通过AV进行查找处理。结构如下:

3.struct anon_vma_chain,简称AVC;AVC是连接VMAAV之间的桥梁。

来一张图就清晰明了了:

图片
  • 通过same_vma链表节点,将anon_vma_chain添加到vma->anon_vma_chain链表中;

  • 通过rb红黑树节点,将anon_vma_chain添加到anon_vma->rb_root的红黑树中;

2. 流程分析

先看一下宏观的图:

图片
  • 地址空间VMA可以通过页表完成虚拟地址到物理地址的映射;

  • 页框与page结构对应,page结构中的mapping字段指向anon_vma,从而可以通过RMAP机制去找到与之关联的VMA

2.1 anon_vma_prepare

之前在page fault的文章中,提到过anon_vma_prepare函数,这个函数完成的工作就是为进程地址空间中的VMA准备struct anon_vma结构。

调用例程及函数流程如下图所示:

图片

至于VMA,AV,AVC三者之间的关联关系,在上文的图中已经有所描述。

当创建了与VMA关联的AV后,还有关键的一步需要做完,才能算是真正的把RMAP通路打通,那就是让pageAV关联起来。只有这样才能通过page找到AV,进而找到VMA,从而完成对应的PTE unmmap操作。

图片

2.2 子进程创建anon_vma

父进程通过fork()来创建子进程,子进程会复制整个父进程的地址空间及页表。子进程拷贝了父进程的VMA数据结构内容,而子进程创建相应的anon_vma结构,是通过anon_vma_fork()函数来实现的。

anon_vma_fork()效果图如下:

图片

以实际fork()两次为例,发生COW之后,看看三个进程的链接关系,如下图:

图片

2.3 TTU(try to unmap)Rmap Walk

如果有page被映射到多个虚拟地址,可以通过Rmap Walk机制来遍历所有的VMA,并最终调用回调函数来取消映射。

与之相关的结构体为struct rmap_walk_control,如下:


取消映射的入口为try_to_unmap,流程如下图所示:

图片

基本的套路就是围绕着struct rmap_walk_control结构,初始化回调函数,以便在适当的时候能调用到。

关于取消映射try_to_unmap_one的详细细节就不进一步深入了,把握好大体框架即可。

原文作者:LoyenWang



详细讲解Linux内存管理之RMAP的评论 (共 条)

分享到微博请遵守国家法律