
void __do_page_fault(...) { if (unlikely(fault_in_kernel_space(address)))
do_kern_addr_fault(regs, hw_error_code, address);
else
do_user_addr_fault(regs, hw_error_code, address);... }
do_kern_addr_fault()
--> vmalloc_fault()
do_user_addr_fault()
--> handle_mm_fault()
--> handle_pte_fault()
对于anonymous page,用户空间使用malloc()进行内存申请时,内核并不会立刻为其分配物理内存。只有当内存被真正使用,触发page fault,才会真正分配物理页面和对应的页表项,即demand alloction,对应的函数实现是do_anonymous_page()。通过mmap映射建立的heap和stack等内存区域,在初始未使用时,也适用于这样的规则。

对于page cache, 在发生内存回收后,部分text(code)段的页面会被discard,部分data段的页面会被writeback,之后再次访问这些页面,也将出现page fault。此时,需要从外部存储介质中,将页面内容调回内存,即demand paging,对应的函数实现是do_fault()。
vm_fault_t handle_pte_fault(struct vm_fault *vmf) {
if (!vmf->pte) {
if (vma_is_anonymous(vmf->vma))
return do_anonymous_page(vmf);
else
return do_fault(vmf);
}
...}
/* orig_pte是指发生page fault时的PTE */ if (!pte_present(vmf->orig_pte))
return do_swap_page(vmf);

struct vm_area_struct vma = find_vma(mm, address); if (unlikely(!vma)) {
bad_area(regs, hw_error_code, address);return; } if(likely(vma->vm_start <= address))
goto good_area;

文章转载自术道经纬,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




