当前位置:首页 >热点 >图解内存匿名反向映射Reverse Mapping 从而可以对目标页做一些操作

图解内存匿名反向映射Reverse Mapping 从而可以对目标页做一些操作

2024-06-29 06:06:29 [百科] 来源:避面尹邢网

图解内存匿名反向映射Reverse Mapping

作者:理查德 存储 存储软件 反向映射的图解目的是为了找到所有映射到某一个页面的页表项,从而可以对目标页做一些操作,内存匿名比如切断映射。映射

 [[342467]]

反向映射的图解目的是为了找到所有映射到某一个页面的页表项,从而可以对目标页做一些操作,内存匿名比如切断映射。映射

图解内存匿名反向映射Reverse Mapping 从而可以对目标页做一些操作

反向映射一直是图解一个非常神奇的存在,今天我们就好好探索一下这个知识点。内存匿名

图解内存匿名反向映射Reverse Mapping 从而可以对目标页做一些操作

创建

图解内存匿名反向映射Reverse Mapping 从而可以对目标页做一些操作

在反向匿名映射中除了page struct,映射一共有三个相关的图解数据结构:

  • vm_area_struct
  • anon_vma
  • anon_vma_chain

第一个数据结构我们已经见过了,是内存匿名一个老朋友。而后两者就是映射为了构造反向匿名映射而新生的。我们先来看看这两个新的图解数据结构的样子。

anon_vma

  1. anon_vma 
  2.     +----------------------------+ 
  3.     |root                        |  = self 
  4.     |parent                      |  = self 
  5.     |    (struct anon_vma*)      | 
  6.     |refcount                    |  = 1 
  7.     |    (atomic_t)              | 
  8.     |degree                      |  = 1 
  9.     |    (unsigned)              | 
  10.     +----------------------------+ 

这个结构由anon_vma_alloc()函数统一生成,内存匿名上图中也显示了创造出来时候的映射样子。从这里看,也就是个带有上下级关系的这么一个结构。

anon_vma_chain

  1. anon_vma_chain 
  2.    +----------------------------+ 
  3.    |vma                         | 
  4.    |    (struct vm_area_struct*)| 
  5.    |anon_vma                    | 
  6.    |    (struct anon_vma*)      | 
  7.    |                            | 
  8.    |rb                          | 
  9.    |    (struct rb_node)        | 
  10.    |same_vma                    | 
  11.    |    (struct list_head)      | 
  12.    +----------------------------+ 

这个结构由anon_vma_chain_alloc()统一创建,貌似创建完了也不需要初始化,拿来后面就直接用了。

组合

到这里,大家应该感觉怪怪的,都不知道这些东西是个啥。别急,我把这些东西组合起来,可能你就会有一些感觉了。

 

在这里,我们把这三个重要的数据结构之间的组合关系展现给大家。当然这只是最简单的组合关系,目的是为了让大家能有一个感性的认识。

  • anon_vma_chain链接了anon_vma和vma
  • vma则会有指针指向自己的anon_vma

空口无凭,眼见为实。那为什么会长成这样的呢?接下来我们就来看看在内核中我们是如何将这些数据结构链接起来的。

链接

上一节的最后,我们看到了三个重要的数据结构通过链表和树连接在了一起,这一节我们就来看看他们是怎么连接起来的。

anon_vma_chain_link

往简单了讲,要连接这三个重要的数据结构,都靠一个函数:anon_vma_chain_link(vma, avc, anon_vma)。而这个函数本身简单到令人发指,以至于我能把整个定义给大家展示出来。

  1. static void anon_vma_chain_link(struct vm_area_struct *vma, 
  2.                     struct anon_vma_chain *avc, 
  3.                     struct anon_vma *anon_vma) 
  4.     {  
  5.         avc->vma = vma; 
  6.         avc->anon_vma = anon_vma; 
  7.         list_add(&avc->same_vma, &vma->anon_vma_chain); 
  8.         anon_vma_interval_tree_insert(avc, &anon_vma->rb_root); 
  9.     } 

你对照这上面的图一看,和图上显示的一摸一样没有任何多余的步骤。

但是,关键的但是来了,如果你以为一切就这这么简单,那就too young too simple了啊。

接下来我们将从anon_vma_chain_link函数被调用的关系入手,去看看在实际运行中究竟会演化出什么样的变化来。

do_anonymous_page

首先出场的是函数do_anonymous_page,这个函数是在匿名页缺页中断时会调用的函数。

  1. do_anonymous_page(vmf) 
  2.         __anon_vma_prepare(vma) 
  3.             avc = anon_vma_chain_alloc() 
  4.             anon_vma = find_mergeable_anon_vma(vma) 
  5.             anon_vma = anon_vma_alloc() 
  6.             vma->anon_vma = anon_vma 
  7.             anon_vma_chain_link(vma, avc, anon_vma) 

从上面的流程可以看出,当发生缺页中断时,内核会给对应的vma构造anon_vma,并且利用avc去链接这两者。这种可以说是系统中最简单的例子,也是上图中显示的情况。

细心的人可能已经看到了,上面有一种情况是find_mergeable_anon_vma。如果这个函数返回一个可以重用的anon_vma,那么内核就可以利用原有的anon_vma了。此时这个图我们可以画成这样。

  1.       .......................      

    (责任编辑:百科)

    推荐文章
    热点阅读