6

Based on my research on mmap(), I understand that mmap uses demand paging to copy in data to the kernel page cache only when the virtual memory address is touched, through page fault.

If we are reading files that are bigger than the page cache, then some stale page in the page cache will have to be swapped out reclaimed. So my question is, will the page table be updated to map the corresponding virtual memory address to the address of the old stale page in the cache (now containing new data)? How does this happen? Is this part of the mmap() system call?

0

1 Answer 1

10

will the page table be updated to map the corresponding virtual memory address to the address of the old stale page in the cache (now containing new data)? How does this happen?

When mmap() is called, it creates a mapping in the process's virtual address space to the file specified. This mapping merely sets up the ability for these pages to be loaded when they are actually accessed, it doesn't load anything into memory yet. When you then access the pages, a page fault is generated, the page table entries are updated to map the virtual addresses to the physical addresses of the newly loaded pages, and you can then access the file. This happens in filemap_fault.

This is also how it works if you access a mapped page which has been evicted: the kernel handles the page fault, puts the file content back into the pages, and from the application's perspective, nothing happened.

There's nothing special about mmap() here per se -- this is how demand paging works inside the Linux kernel in general, as used for almost everything -- even regular program memory and file cache entries.

[...] map the corresponding virtual memory address [...]

Note that, when reading in with mmap(), the kernel typically will use readahead in order to load more content than just the single page you've generated a page fault on, unless there is an indication that this would be unhelpful, like MADV_RANDOM (indicated by user), or MMAP_LOTSAMISS (kernel heuristic).

9
  • Good answer, so I don't want to add another one, but I think you missed one of the most important system calls in this context, madvise, and especially the MADV_DONTNEED flag: "Do not expect access in the near future. (For the time being, the application is finished with the given range, so the kernel can free resources associated with it.) Subsequent accesses of pages in this range will succeed, but will result either in reloading of the memory contents from the underlying mapped file (see mmap(2)) or zero-fill-on-demand pages for mappings without an underlying file".
    – aviro
    Apr 3 at 8:19
  • At least for me, at the time, it made things much clearer on the way of negation.
    – aviro
    Apr 3 at 8:20
  • @aviro Could you explain a bit more about why you think MADV_DONTNEED would be helpful to mention? The answer is asking about reclaim-based eviction, which has different semantics.
    – Chris Down
    Apr 3 at 12:59
  • Because it shows that the mapped file doesn't even has to stay at the page cache and will be reclaimed after each read, regardless of the available memory. If you don't see the value of that, I can write down an answer with the explanation.
    – aviro
    Apr 3 at 13:58
  • For now I put a mention of MADV_DONTNEED next to MADV_RANDOM. (MADV_DONTNEED doesn't guarantee reclamation after read, though, maybe you were thinking of other controls)
    – Chris Down
    Apr 3 at 16:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .