ITz*_*ITz 4 fork copy-on-write virtual-memory linux-kernel page-tables
我搜索了很多资源,但没有发现任何具体的问题:
我知道在某些 linux 系统中,fork()系统调用与 copy-on-write 一起使用;也就是说,父子进程共享相同的地址空间,但是 PTE 现在被标记为read-only,以便稍后在 COW 中使用。当任何一个尝试访问一个页面时,PAGE_FAULT都会发生一个页面,并将该页面复制到另一个可以修改的地方。
但是,我无法理解操作系统如何到达共享 PTE 以将它们标记为“已读”。我假设当fork()系统调用发生时,操作系统在父页表上执行“页面遍历”并将它们标记为只读- 但我没有找到对此的确认,或有关该过程的任何信息。
有谁知道这些页面是如何被标记为只读的?将不胜感激任何帮助。谢谢!
Linux 操作系统通过迭代mmap父进程的所有内存范围(s、堆栈和堆)来实现系统调用 fork 。该范围的复制(VMA -虚拟内存区域在功能 copy_page_range(mn/memory.c)中,它在页表条目上循环:
copy_page_range将遍历 pgd并调用copy_pud_range 迭代pud并调用copy_pmd_range 迭代 pmd 并调用copy_pte_range 迭代 pte 并调用copy_one_pte 它执行内存使用记录 (RSS) 并有几个代码段来处理 COW 情况: /*
* If it's a COW mapping, write protect it both
* in the parent and the child
*/
if (is_cow_mapping(vm_flags)) {
ptep_set_wrprotect(src_mm, addr, src_pte);
pte = pte_wrprotect(pte);
}
Run Code Online (Sandbox Code Playgroud)
whereis_cow_mapping对私有页面和潜在可写页面为真(检查共享位和maywrite 位的位域标志,并且应该只设置 maywrite 位)
#define VM_SHARED 0x00000008
#define VM_MAYWRITE 0x00000020
static inline bool is_cow_mapping(vm_flags_t flags)
{
return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
}
Run Code Online (Sandbox Code Playgroud)
PUD、PMD 和 PTE 在https://www.kernel.org/doc/gorman/html/understand/understand006.html等书籍和LWN 2005:“四级页表合并”等文章中都有描述。
fork 实现如何调用copy_page_range:
do_fork(kernel/fork.c) 它将调用copy_process这将调用许多 copy_* 函数,包括copy_mm 其中调用dup_mm 分配和填充新的 mm 结构,其中大部分工作由 dup_mmap(仍然是 kernel/fork.c),它将检查什么是 mmaped 以及如何。(在这里我无法获得 COW 实现的确切路径,所以我使用 Internet Search Machine 和类似“fork+COW+dup_mm”的东西来获取类似[1]或[2]或[3] 的提示)。在检查 mmap 类型后,retval = copy_page_range(mm, oldmm, mpnt);可以进行实际工作。| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |