Β§20.3–20.6Multi-level Page Tables … Summary

Part I OSTEP pp. 219–227 Β· ~7 min read

  • multi-level page table
  • page directory
  • page-directory entry
  • inverted page table

Forget segments β€” attack the waste directly: why keep the invalid regions of the page table in memory at all?

20.3 Multi-level Page Tables

The multi-level page table turns the linear array into a tree, and it is so effective that most modern systems use it (x86 included). Two moves: chop the page table into page-sized units; if an entire page of PTEs is invalid, don’t allocate that page at all. A new structure β€” the page directory β€” records which pieces exist: each page-directory entry (PDE) holds a valid bit and a PFN, where valid means β€œat least one PTE on the page I point to is valid.” Invalid PDE β†’ that whole slice of the table simply isn’t there. The multi-level table makes parts of the linear page table disappear, freeing those frames for real work.

Two structural advantages: page-table space is allocated in proportion to the address space you actually use β€” sparse spaces, finally handled honestly; and each piece fits neatly in a page, so growing a table means grabbing any free frame β€” no hunt for 4MB of contiguous memory, because the directory’s indirection lets pieces live anywhere. The costs: on a TLB miss, two memory loads (PDE, then PTE) rather than one β€” a time-space trade-off β€” and undeniably more complexity in the lookup, wherever it runs.

A Detailed Multi-Level Example

A 16KB address space with tiny 64-byte pages: 14-bit addresses, 8-bit VPN, 6-bit offset. A linear table needs 256 entries (1KB = sixteen 64-byte pages of 16 PTEs each) β€” for this:

Figure 20.4: the 16KB space at 64-byte grain β€” 256 pages, six of them real
0x00000x00800x0100(free) β€” VPNs 6 … 253: all free β“˜0x01800x3F800x4000

click a region marked β“˜ for details

The VPN now splits in two: the top 4 bits index the directory (16 entries, one per page of the table), the bottom 4 index within the chosen page:

PDEAddr = PageDirBase + (PDIndex * sizeof(PDE))
// if PDE valid:
PTEAddr = (PDE.PFN << SHIFT) + (PTIndex * sizeof(PTE))

Only three pages exist where sixteen would have been: the directory, and the two pieces of the table with valid mappings. Walk any address through it:

Figure 20.5, live: page directory + the two surviving pages of the page table. Presets: the book's 0x3F80, code, heap, and both fault flavors.

virtual address

16256

11111110000000

β†’

page directorymemory access #1

1. PDIndex = top 4 bits = 15

2. PD[15] β†’ PT page @ PFN 101 βœ“

β†’

page of the page tablememory access #2

3. PTEAddr = (101 β‰ͺ 6) + 14Γ—4 = 6520

4. PTE β†’ PFN 55, rw- βœ“

β†’

physical address

3520

Page Directory
idxPFNv
01001
1β€”0
2β€”0
3β€”0
4β€”0
5β€”0
6β€”0
7β€”0
8β€”0
9β€”0
10β€”0
11β€”0
12β€”0
13β€”0
14β€”0
15 β—€1011
Page of PT (@PFN:100)
idxPFNvprot
0101r-x
1231r-x
2β€”0β€”
3β€”0β€”
4801rw-
5591rw-
6β€”0β€”
7β€”0β€”
8β€”0β€”
9β€”0β€”
10β€”0β€”
11β€”0β€”
12β€”0β€”
13β€”0β€”
14β€”0β€”
15β€”0β€”
Page of PT (@PFN:101)
idxPFNvprot
0β€”0β€”
1β€”0β€”
2β€”0β€”
3β€”0β€”
4β€”0β€”
5β€”0β€”
6β€”0β€”
7β€”0β€”
8β€”0β€”
9β€”0β€”
10β€”0β€”
11β€”0β€”
12β€”0β€”
13β€”0β€”
14 β—€551rw-
15451rw-

The tour: 16256 (0x3F80) β†’ PDIndex 1111 β†’ PD[15] β†’ PT page @101; PTIndex 1110 β†’ PFN 55; PA = (55 β‰ͺ 6) | 0 = 3520 = 0x0DC0 β€” the book's worked example. 0 β†’ code at 640. 320 (VPN 5, heap) β†’ 3776. 128 (VPN 2) β†’ the PT page EXISTS but the PTE is invalid: level-2 fault. 8192 (VPN 128) β†’ PD[8] invalid: level-1 fault β€” the entire middle was never allocated. Note the two violet "memory access" badges: that's the time half of the time-space trade.

More Than Two Levels

The goal is that every piece of the structure fits in a page β€” the directory included. Take a 30-bit space with 512-byte pages: 21-bit VPN, 9-bit offset; 128 PTEs fit per page, so the page-table index takes 7 bits… leaving 14 bits of directory index. A 2¹⁴-entry directory spans 128 pages β€” goal destroyed. The remedy is recursion: split the directory itself and add a level above it:

PD Index 0 (7)PD Index 1 (7)PT Index (7)offset (9)

Each added level is another load on a miss β€” x86-64 walks four. Whew: a lot of work, all just to look something up in a tree.

The Translation Process: Remember The TLB

The full per-reference control flow, TLB first (Figure 20.6):

VPN = (VirtualAddress & VPN_MASK) >> SHIFT
(Success, TlbEntry) = TLB_Lookup(VPN)
if (Success == True)    // TLB Hit
    if (CanAccess(TlbEntry.ProtectBits) == True)
        Offset   = VirtualAddress & OFFSET_MASK
        PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
        Register = AccessMemory(PhysAddr)
    else
        RaiseException(PROTECTION_FAULT)
else                    // TLB Miss
    PDIndex = (VPN & PD_MASK) >> PD_SHIFT
    PDEAddr = PDBR + (PDIndex * sizeof(PDE))
    PDE     = AccessMemory(PDEAddr)
    if (PDE.Valid == False)
        RaiseException(SEGMENTATION_FAULT)
    else
        PTIndex = (VPN & PT_MASK) >> PT_SHIFT
        PTEAddr = (PDE.PFN << SHIFT) + (PTIndex * sizeof(PTE))
        PTE     = AccessMemory(PTEAddr)
        if (PTE.Valid == False)
            RaiseException(SEGMENTATION_FAULT)
        else if (CanAccess(PTE.ProtectBits) == False)
            RaiseException(PROTECTION_FAULT)
        else
            TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
            RetryInstruction()

On a hit, nothing changed. Only a miss pays the two extra AccessMemory calls β€” the smaller table’s whole price, collected only when the cache fails.

Tip: Be Wary Of Complexity

A good systems builder implements the least complex system that achieves the task. As Saint-ExupΓ©ry wrote: β€œPerfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away.” (What he didn’t write: it’s a lot easier to say something about perfection than to achieve it.) Here, complexity was purchased deliberately β€” deeper lookups in exchange for precious memory.

20.4 Inverted Page Tables

The extreme point in the design space: keep one table for the whole system, with an entry per physical frame recording which process uses it and which of that process’s virtual pages maps there. Finding a translation becomes a search β€” in practice a hash table built over the structure (the PowerPC’s approach). The inverted page table makes the chapter’s moral explicit: page tables are just data structures, and data structures can be made smaller, bigger, faster, slower β€” whatever the constraints reward.

20.5 Swapping The Page Tables To Disk

One last assumption quietly relaxed: even shrunken tables might not fit in physical memory. Some systems therefore place page tables in kernel virtual memory, letting the tables themselves be swapped to disk under pressure. How anything moves between memory and disk is the next chapters’ story β€” and the VAX/VMS case study will show this trick in production.

20.6 Summary

Real page tables are built as trees, hashes, and hybrids β€” not just arrays β€” each choice trading time against space: bigger tables serve misses faster; smaller tables give memory back. Memory-tight systems choose small structures; memory-rich systems running page-hungry workloads may prefer big flat ones. And with software-managed TLBs, the entire data-structure universe belongs to the OS innovator β€” that’s you. Dream the big dreams only operating-system developers can dream.

Homework: paging-multilevel-translate.py

Count the registers needed to locate a two-level table, then a three-level one; translate addresses under random seeds and verify with -c, counting memory references per lookup; then reason about how page-table accesses behave in the hardware CACHES (hits or misses? why?). Get it at ostep-homework.

Check yourself

1.State the multi-level page table's basic idea in two moves.

2.In the 16KB example (64-byte pages, 8-bit VPN), translate 0x3F80 β€” the 0th byte of VPN 254.

3.What does the multi-level structure pay for its compactness, and when is the bill collected?

4.With 512-byte pages and a 30-bit address space, two levels aren't enough. Why, and what's the fix?

5.The inverted page table turns the whole design inside out. How?

5 questions