Linux内存管理 -反向映射RMAP

所谓反向映射是相对于从虚拟地址到物理地址的映射,反向映射是从物理页面到虚拟地址空间VMA的反向映射。

RMAP能否实现的基础是通过struct anon_vma、struct anon_vma_chain和sturct vm_area_struct建立了联系,通过物理页面反向查找到VMA。

用户在使用虚拟内存过程中,PTE页表项中保留着虚拟内存页面映射到物理内存页面的记录。

一个物理页面可以同时被多个进程的虚拟地址内存映射,但一个虚拟页面同时只能有一个物理页面与之映射。

不同虚拟页面同时映射到同一物理页面是因为子进程克隆父进程VMA,和KSM机制的存在。

如果页面要被回收,就必须要找出哪些进程在使用这个页面,然后断开这些虚拟地址到物理页面的映射。

匿名页面实际的断开映射操作在rmap_walk_anon中进行的,可以看出从struct page、到struct anon_vma、到struct anon_vma_chain、到struct vm_area_struct的关系。

1. 父进程分配匿名页面

父进程为自己的进程地址空间VMA分配物理内存时,通常会产生匿名页面。

do_anonymous_page()会分配匿名页面;do_wp_page()发生写时复制COW时也会产生一个新的匿名页面。

static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
        unsigned long address, pte_t *page_table, pmd_t *pmd,
        unsigned int flags)
{
...
    /* Allocate our own private page. */
    if (unlikely(anon_vma_prepare(vma)))------------------------------为进程地址空间准备struct anon_vma数据结构和struct anon_vma_chain链表。
        goto oom;
    page = alloc_zeroed_user_highpage_movable(vma, address);----------从HIGHMEM区域分配一个zeroed页面
    if (!page)
        goto oom;
...
    inc_mm_counter_fast(mm, MM_ANONPAGES);
    page_add_new_anon_rmap(page, vma, address);-----------------------
    mem_cgroup_commit_charge(page, memcg, false);
    lru_cache_add_active_or_unevictable(page, vma);
...
}

RMAP反向映射系统中有两个重要的数据结构:一个是struct anon_vma,简称AV;一个是struct anon_vma_chain,简称AVC。

struct anon_vma {
    struct anon_vma *root;        /* Root of this anon_vma tree */----------------指向anon_vma数据机构中的根节点
    struct rw_semaphore rwsem;    /* W: modification, R: walking the list */------保护anon_vma中链表的读写信号量
    /*
     * The refcount is taken on an anon_vma when there is no
     * guarantee that the vma of page tables will exist for
     * the duration of the operation. A caller that takes
     * the reference is responsible for clearing up the
     * anon_vma if they are the last user on release
     */
    atomic_t refcount;------------------------------------------------------------对anon_vma的引用计数

    /*
     * Count of child anon_vmas and VMAs which points to this anon_vma.
     *
     * This counter is used for making decision about reusing anon_vma
     * instead of forking new one. See comments in function anon_vma_clone.
     */
    unsigned degree;

    struct anon_vma *parent;    /* Parent of this anon_vma */--------------------指向父anon_vma数据结构

    /*
     * NOTE: the LSB of the rb_root.rb_node is set by
     * mm_take_all_locks() _after_ taking the above lock. So the
     * rb_root must only be read/written after taking the above lock
     * to be sure to see a valid next pointer. The LSB bit itself
     * is serialized by a system wide lock only visible to
     * mm_take_all_locks() (mm_all_locks_mutex).
     */
    struct rb_root rb_root;    /* Interval tree of private "related" vmas */-----红黑树根节点
}

struct anon_vma_chain数据结构是链接父子进程的枢纽:

struct anon_vma_chain {
    struct vm_area_struct *vma;-----------------------------------------------指向VMA
    struct anon_vma *anon_vma;------------------------------------------------指向anon_vma数据结构,可
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值