内核版本:Linux-5.14
在linux内核执行fork完毕后,原先父进程中可写的区域在父子进程中都被设置为了CoW,即将pte中可写的比特清除了。
下面是调用流程:[kernel/fork.c]
sys_fork -> kernel_clone -> copy_process -> copy_mm -> dup_mm -> dup_mmap -> copy_page_range -> copy_p4d_range -> 如果时PUD巨型页:copy_huge_pud: 分别将父子的PUD页表项设置为写保护 -> pudp_set_wrprotect(src_mm, addr, src_pud); -> set_pud_at(dst_mm, addr, dst_pud, pud_mkold(pud_wrprotect(pud))); -> copy_pmd_range -> 如果是PMD巨型页:copy_huge_pmd: 分别将父子的PMD页表项设置为写保护 -> pmdp_set_wrprotect(src_mm, addr, src_pmd); -> set_pmd_at(dst_mm, addr, dst_pmd, pmd_mkold(pmd_wrprotect(pmd))); -> copy_pte_range -> copy_present_pte -> 如果:is_cow_mapping(vm_flags) && pte_write(pte) -> ptep_set_wrprotect(src_mm, addr, src_pte); -> set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte_wrprotect(pte));
如果上面的显示被自动换行了,可以点击代码右上角的全屏按钮查看