作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我搜索了很多资源,但没有发现任何具体的问题:
我知道对于某些 linux 系统,fork()
系统调用与写时复制一起工作;即父子共享同一个地址空间,但PTE现在标记为只读 , 稍后在 COW 中使用。当任一尝试访问页面时,PAGE_FAULT
发生并且页面被复制到另一个可以修改的地方。
但是,我无法理解操作系统如何到达共享 PTE 以将它们标记为“已读”。我假设当 fork()
系统调用发生时,操作系统在父页表上执行“页面遍历”并将它们标记为 只读 - 但我没有找到对此的确认,或有关该过程的任何信息。
有谁知道这些页面是如何被标记为只读的?将不胜感激任何帮助。谢谢!
最佳答案
Linux 操作系统通过迭代父进程的所有内存范围(mmap
s、堆栈和堆)来实现系统调用 fork。该范围的复制(VMA - Virtual memory areas 位于函数 copy_page_range
(mn/memory.c) 中,该函数具有循环页表条目:
copy_page_range
将iterate over 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);
}
is_cow_mapping
对于私有(private)页面和潜在可写页面为真(检查位域标志是否为共享和
maywrite bits 并且应该只设置 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;
}
copy_page_range
:
do_fork
(kernel/fork.c) 将调用 copy_process
将调用 many copy_* functions ,包括 copy_mm
调用 dup_mm
分配和填充新的 mm 结构,其中大部分工作由 dup_mmap
(仍然是 kernel/fork.c),它将检查映射了什么以及如何映射。 (在这里,我无法获得 COW 实现的确切路径,因此我使用 Internet Search Machine 和类似“fork+COW+dup_mm”的东西来获得类似 [1] 或 [2] 或 [3] 的提示)。检查 mmap 类型后有 retval = copy_page_range(mm, oldmm, mpnt);
行做实际工作。 关于linux-kernel - fork() 进程如何将父级的 PTE 标记为只读?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60363929/
我是一名优秀的程序员,十分优秀!