Reputation: 414
From what I know frames that are used by the kernel are not swapped to the disk, then how can a page fault occur in kernel mode? Is it possible? When?
Upvotes: 0
Views: 2080
Reputation: 9523
From Intel CPU point of view: yes, it is possible. Not all addresses are available (mapped), so you may get a page fault. Kernel should distinguish the origin of the fault. Kernel could access user space memory (e.g. to clone a process), so it could cause page faults. Linux kernel keep all kernel memory in physical memory, just for sake of simplicity, but this is not an hard requirement.
Note: a page fault (or any other exception) inside an exception will cause a double fault exception, handled differently, and an exception inside double fault handler will cause a triple fault, which it is hardcoded as a CPU reset. (sometime this trick was used to return to real mode, hopefully for short time).
Upvotes: 0
Reputation: 69276
Yes, it very well can. A page fault is not a "bad thing" as is. Sure, it can mean that user code is running into a segmentation fault trying to access invalid memory, but it can also mean other things. For example, a page fault happens whenever you write to a page for the first time after mapping it (if mapped without MAP_POPULATE
). This kind of fault can easily happen in kernel code if the first operation on the mapping happens as part of a syscall, for example mmap(); read()
.
You can use the perf
tool if you want to take a quick look at kernel functions that generate page faults to get an idea of different ways in which page faults can happen in kernel mode.
And here's an example on a test program:
#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
Upvotes: 1