Today's Outline
- virtual memory
- page tables
- Translation Lookaside Buffer
- page replacement
- page faults
Virtual Memory
- for reasons of
- security: to prevent programs from corrupting each other and the OS
- flexibility: to dynamically move parts of programs (code and data)
from memory to disk and back
the virtual memory address given to the memory subsystem is
converted by the MMU into a physical memory address
- to do this, the memory is divided into equal-sized pages,
e.g 4K long:
- the high bits of the address is the page number
- the low bits of the address are the page offset
- paging relies on locality: accesses are not
randomly distributed over the virtual memory, but tend to be
over a small set of pages, the working set
paging example
- carefully study example 4-10 on p. 204:
- for example, virtual address 0x05123 corresponds to
the physical address 0x03123, since virtual page 5 is
mapped to physical page 3
- for example, virtual address 0x06123 is not mapped --
any access to this will cause a page fault interrupt
- pages can easily be shared among processes, e.g. for shared
memory or dynamically loaded libraries
page tables
- table of virtual-to-physical translation
- indexed by the hardware: given a virtual page number, obtain
the physical page number
- such page tables need an entry for each possible virtual page,
so can be very large for 64-bit processors
- inverted page table: table of entries, one per physical page,
showing corresponding virtual address (used in Linux 2.6, e.g. see
Love p. 164) has fewer entries for 64-bit processors
- page table must also contain protection bits, e.g. R, W, X
- page table must also contain one bit to record if the page
is mapped
- page table usually also contains at least one bit to record
if the page has been modified -- if so, the OS must write the page
back to disk before freeing it
page table use
- on every memory access, Memory Management Unit (MMU) must:
- load the page table entry from physical memory
- use this to compute the physical address of the memory access
- perform the desired memory access
- thanks to locality, the number of pages accessed at any given
time is small
- a small buffer working as a cache can avoid the need for the
first memory access in most cases, making the average case fast
Translation Lookaside Buffer
- TLB
- hardware-maintained associative table giving physical equivalents
for virtual page numbers
- 8-64 entries cached in the TLB, must be reloaded:
- by hardware (or by software), if using regular page tables
- by software, if using inverted page tables
- TLB works as a cache, so when the translation is not found
(and unless the TLB is reloaded by hardware), the result is a TLB miss,
handled by an interrupt handler
- the TLB miss handler must find the correct virtual-to-physical
translation and place it in the TLB
page faults
- A virtual page is in one of two places:
- in physical memory, or
- on disk, usually in a reserved space called swap space
- a read-only virtual page loaded from disk (e.g. see mmap(2))
can also be backed by the regular disk rather than the swap space
- for any actual access, a page must be in physical memory
- an access to an unmapped page causes a page fault
- the page fault handler must map the page
- if the memory is full, the page fault handler must evict one
of the resident pages
page replacement
- ideally, evict the page that will be referenced last among all
the pages in memory
- also, evicting a page that hasn't been modified avoids a write
to disk
- LRU (least recently used) uses the past to predict the future,
but requires high overhead
- instead, periodically mark all pages as unused, and update the
bit whenever a page is referenced. At the end of the period, any
pages with the bit still clear are Not Recently Used (NRU) and can
be evicted
page replacement implementation
- most MMUs do not mark pages used on each access
- instead, the OS can mark the page as unmapped (but still keep it
in physical memory)
- the first access to that page causes a page fault, which allows
the page fault handler to mark the page as used (as well as map the page)
- to correctly keep the dirty bit recording
whether the page has been written, a page mapped in the previous
step can be marked read-only (if the access was a read), causing
an access violation on the first write
- Copy-on-Write (COW) lets the page fault handler copy a page
if it is written to -- very useful for quick implementation of fork(2)
Copy on Write and fork
- fork() logically does a copy of the entire process
- this would be very expensive to implement with an actual copy
- instead, fork assigns the same physical pages to both processes,
and marks all of them read-only (even the ones that the process can
write to)
- when the hardware reports a protection violation, the page fault
handler can copy the relevant page only, leaving the rest shared
- in this way, fork is very cheap
- only works because the page offsets are the same in both processes...
when demand exceeds supply
- virtual memory can give the illusion of more memory than there
is physical RAM
- however, even virtual memory is limited -- the sums of all the
process sizes should not exceed the size of RAM plus swap space
- also, once swap is used, good performance depends on locality
- if many processes have to access virtual memory that is in
the swap space, they will make little progress
- while one page is being fetched from swap, another one (in the
working set) may get swapped out
- a system doing this is said to be thrashing
page fault outline
- locate a free page
- locate the page on the disk
- issue a read request to the disk system
- when the page is ready, put it into memory (may be done by DMA)
- restart the process that page faulted by re-executing the
instruction that faulted
- kernel pages for the disk system should never be evicted, so
they are kept locked, wired down, or pinned
- same for real-time processes
free page pool
- it is a good idea for the
OS to always have some free pages, so page faults can be addressed
- a process or thread (e.g. kswapd in linux -- see also
this
description
and also
here) tries to make sure there are always pages available
- if not, candidate pages are freed, either directly for clean
pages, or by writing to disk the dirty pages