最近在读linux内核代码的内存管理部分(我读的版本是4.10)。我发现mremap的实现很奇怪。
简而言之,sys_mremap()
will call move_vma()
,它基本上会执行以下操作:
copy_vma()
move_page_tables()
do_munmap()
步骤1和2很容易理解,它们只是从旧的内存映射复制到新的映射中。但是,在这两个步骤中复制到新的内存映射时,它们不会增加结构页的引用计数(我在源代码中没有找到它)。
然后在步骤 3 中,内核将取消旧映射的映射。它迭代每个 vma 和每个页面,减少 struct page 的引用计数,最后调用tlb_flush_mmu_free()
释放所有页面。
我的问题是:
- 如果内核这样实现mremap,下面对页面的访问会导致页面错误吗?
- 为什么内核不增加引用计数
move_vma()
? mremap后它会将页面保留在内存中,并且不会导致不必要的页面错误。 - 匿名和私有映射页面怎么样?此类页面被释放后,用户如何访问内容?