缺页中断发送后,根据pte页表项的PRESENT位、pte内容是否为空(pte_none()宏)以及是否为文件等条件,相应的处理函数如下:
1、匿名页面缺页中断do_anonymous_page()
(1) 判断条件: pte页表项中PRESENT没有置位、pte内容为空且没有指定vma->vm_ops->fault()函数指针。
(2) 应用场合: malloc()分配内存。
2、文件映射缺页中断do_fault()
(1) 判断条件:pte页面表项中的PRESENT没有置位、pte内容为空且指定了vma->vm_ops->fault()函数指针。do_fault()属于在文件映射中发生的缺页中断的情况。
-
如果仅发生读错误,那么调用do_read_fault()函数取读取整个页面。
-
如果私有映射VMA中发生写保护错误,那么发生写时复制,新分配一个页面new_page,旧页面的内容要复制到新页面中,利用新页面生成一个PTE entry,并设置到硬件页表中,就这是所谓的写时复制COW。
-
如果写保护错误发生在共享映射VMA中,那么就产生了脏页,调用系统的回写机制来回写这个脏页。
(2) 应用场合:
-
使用mmap读文件内容,例如驱动使用mmap映射设备内存到用户空间等。
-
动态库映射,例如不同的进程可以通过文件映射来共享同一个动态库。
3、swap缺页中断do_swap_page()
判断条件:pte页表项中的PRESENT没有置位且pte页表项内容不为空。
4、写时复制COW缺页中断do_wp_page()
(1) do_wp_page()最终有两种处理情况。
-
reuse复用old_page: 单身匿名页面和可写的共享页面。
-
gotten写时复制:非单身匿名页面、只读或者非共享的文件映射页面。
(2) 判断条件:pte表项中的PRESENT置位了且发生写错误缺页中断。
(3) 应用场景:fork,父进程fork子进程,父子进程都共享父进程的匿名页面,当其中一方需要修改内容时,COW便会发生。