内核模式下会发生页面错误吗?
Can a page fault occur in kernel mode?
据我所知,内核使用的帧不会交换到磁盘,那么在内核模式下如何发生页面错误?可能吗?什么时候?
是的,它很好。页错误并不是一件“坏事”原样。当然,这可能意味着用户代码 运行 进入了试图访问无效内存的分段错误,但它也可能意味着其他事情。例如,每当您在映射页面后第一次写入页面时(如果没有 MAP_POPULATE
进行映射),就会发生页面错误。如果对映射的第一个操作作为系统调用的一部分发生,例如 mmap(); read()
.
,这种错误很容易在内核代码中发生
如果您想快速查看生成页面错误的内核函数,以了解在内核模式下发生页面错误的不同方式,您可以使用 perf
工具。
下面是一个测试程序示例:
#include <sys/mman.h>
#include <unistd.h>
int main(void) {
void *m = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
read(0, m, 1);
return 0;
}
$ gcc x.c
$ sudo perf record -e page-fault:k ./a.out
$ perf report
Samples: 4 of event 'page-faults:k', Event count (approx.): 16
Overhead Command Shared Object Symbol
87.50% a.out [kernel.kallsyms] [k] copy_user_generic_unrolled
12.50% a.out [kernel.kallsyms] [k] __clear_user
从英特尔 CPU 的角度来看:是的,这是可能的。并非所有地址都可用(已映射),因此您可能会遇到页面错误。内核应该区分故障的来源。内核可以访问用户 space 内存(例如克隆一个进程),因此它可能会导致页面错误。 Linux 内核将所有内核内存保留在物理内存中,只是为了简单起见,但这不是硬性要求。
注意:异常中的页面错误(或任何其他异常)将导致双重错误异常,处理方式不同,双重错误处理程序中的异常将导致三重错误,它被硬编码为 CPU 重置。 (有时这个技巧用于 return 到实模式,希望时间短)。
据我所知,内核使用的帧不会交换到磁盘,那么在内核模式下如何发生页面错误?可能吗?什么时候?
是的,它很好。页错误并不是一件“坏事”原样。当然,这可能意味着用户代码 运行 进入了试图访问无效内存的分段错误,但它也可能意味着其他事情。例如,每当您在映射页面后第一次写入页面时(如果没有 MAP_POPULATE
进行映射),就会发生页面错误。如果对映射的第一个操作作为系统调用的一部分发生,例如 mmap(); read()
.
如果您想快速查看生成页面错误的内核函数,以了解在内核模式下发生页面错误的不同方式,您可以使用 perf
工具。
下面是一个测试程序示例:
#include <sys/mman.h>
#include <unistd.h>
int main(void) {
void *m = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
read(0, m, 1);
return 0;
}
$ gcc x.c
$ sudo perf record -e page-fault:k ./a.out
$ perf report
Samples: 4 of event 'page-faults:k', Event count (approx.): 16
Overhead Command Shared Object Symbol
87.50% a.out [kernel.kallsyms] [k] copy_user_generic_unrolled
12.50% a.out [kernel.kallsyms] [k] __clear_user
从英特尔 CPU 的角度来看:是的,这是可能的。并非所有地址都可用(已映射),因此您可能会遇到页面错误。内核应该区分故障的来源。内核可以访问用户 space 内存(例如克隆一个进程),因此它可能会导致页面错误。 Linux 内核将所有内核内存保留在物理内存中,只是为了简单起见,但这不是硬性要求。
注意:异常中的页面错误(或任何其他异常)将导致双重错误异常,处理方式不同,双重错误处理程序中的异常将导致三重错误,它被硬编码为 CPU 重置。 (有时这个技巧用于 return 到实模式,希望时间短)。