ยง19.3โ€“19.5Who Handles The TLB Miss? โ€ฆ TLB Issue: Context Switches

Part I OSTEP pp. 203โ€“207 ยท ~8 min read

  • hardware-managed tlb
  • software-managed tlb
  • fully associative
  • address space identifier

The miss path exists โ€” someone has to walk it. Two very different answers, from two eras of computer architecture.

19.3 Who Handles The TLB Miss?

With a hardware-managed TLB (the CISC tradition โ€” x86 today), the hardware handles misses entirely: it knows the page tableโ€™s location (via CR3) and its exact format, walks it, refills the TLB, retries. With a software-managed TLB (the RISC tradition โ€” MIPS, SPARC), the hardware does almost nothing:

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
    RaiseException(TLB_MISS)

One line โ€” and the OSโ€™s trap handler does the rest. Step through all three paths a reference can take:

Three fates of a memory reference: a hit (either design), a hardware-managed miss, a software-managed miss
Program(user mode)
Hardware (MMU)
OS(kernel mode)
TLB hit โ€” the common case, either design
TLB miss, hardware-managed (CISC โ€” e.g. x86)
TLB miss, software-managed (RISC โ€” e.g. MIPS, SPARC)
step 1 / 15 ยท time flows downward

Program: load from a virtual address

Two details reward attention. The return-from-trap must resume at the faulting instruction โ€” not after it, as with a syscall โ€” so the hardware saves a different PC depending on what caused the trap. And the handler itself must never trigger an infinite chain of TLB misses: keep the handler in unmapped physical memory, or reserve wired, permanently-valid TLB slots for it. The payoff of the software approach: flexibility (the OS can use any page-table structure it wants) and simplicity (the hardwareโ€™s miss path is one line).

Aside: RISC vs. CISC

The 1980sโ€™ great architecture battle. CISC: many powerful instructions โ€” assembly as a high-level language. RISC (Patterson & Hennessy): instruction sets are compiler targets โ€” rip out the microcode, keep few, simple, fast primitives. RISC chips were dramatically faster at first; then CISC vendors absorbed the techniques (micro-instruction pipelines), transistor counts soared, and the debate quietly died. Both run fast today โ€” but the TLB divide (hardware- vs software-managed) still marks the old battlefield.

19.4 TLB Contents: Whatโ€™s In There?

A typical TLB has 32, 64, or 128 entries and is fully associative : any translation can sit in any entry, and the hardware searches them all in parallel. Thatโ€™s why each entry stores both halves of the mapping:

VPNPFNother bits: valid ยท prot ยท ASID ยท dirty ยท โ€ฆ

The โ€œother bitsโ€ carry the interesting state: a valid bit (is a translation cached here?), protection bits (r/w/x, checked on the hit path), and often an address-space identifier and dirty bit.

Aside: TLB Valid Bit โ‰  Page Table Valid Bit

A common mistake. A page table entry marked invalid means the page is not allocated โ€” touching it is a program error, usually fatal. A TLB entry marked invalid merely holds no cached translation โ€” the normal state at boot, and precisely what a flush produces. One bit describes the address space; the other describes a cache.

19.5 TLB Issue: Context Switches

TLB contents are only meaningful for the process that created them. Switch from P1 to P2 and the cache becomes a trap:

The context-switch problem: P1 maps VPN 10 โ†’ PFN 100, P2 maps VPN 10 โ†’ PFN 170 โ€” and the TLB can't tell whose is whose
VPNPFNvalidprot
entry 0101001rwx
entry 1โ€”โ€”0โ€”
entry 2101701rwx
entry 3โ€”โ€”0โ€”
Dotted-underlined cells have explanations โ€” click one.

The Crux: How To Manage TLB Contents On A Context Switch

When context-switching between processes, the translations in the TLB for the last process are not meaningful to the about-to-be-run process. What should the hardware or OS do?

Fix #1 โ€” flush: on every switch, set all valid bits to 0 (via a privileged instruction, or automatically when the PTBR is written โ€” the OS changes it on a switch anyhow). Correct, simple โ€” and every switch now buys a fresh burst of misses as the new process re-touches its pages. Switch frequently and the cost bites.

Fix #2 โ€” tag the entries: an address space identifier (ASID) per entry โ€” think of it as a compact PID (typically ~8 bits). Translations from different processes coexist; the OS just sets a privileged register to the current ASID at switch time:

Fix #2: an address space identifier per entry โ€” now both processes' translations coexist
VPNPFNvalidprotASID
entry 0101001rwx1
entry 1โ€”โ€”0โ€”โ€”
entry 2101701rwx2
entry 3โ€”โ€”0โ€”โ€”
Dotted-underlined cells have explanations โ€” click one.

And the mirror-image situation is not a bug but a feature:

The converse case โ€” two DIFFERENT virtual pages, one physical frame: code sharing at work
VPNPFNvalidprotASID
entry 0101011r-x1
entry 2501011r-x2
Dotted-underlined cells have explanations โ€” click one.

Sharing code pages (binaries, shared libraries) reduces the number of physical pages in use โ€” the payoff protection bits promised back in the segmentation chapter, alive and well under paging.

Check yourself

1.Hardware-managed vs software-managed TLBs: who does what on a miss, and what does the software approach buy?

2.The return-from-trap after a TLB-miss handler differs subtly from the one after a system call. How?

3.The TLB-miss handler is code, and code lives on pages. What stops the handler from TLB-missing on itself, forever?

4.A TLB entry's valid bit reads 0. A page table entry's valid bit reads 0. Same meaning?

5.After a context switch, P2 runs โ€” but the TLB still holds P1's VPN 10 โ†’ PFN 100 while P2 expects VPN 10 โ†’ PFN 170. Compare the two fixes.

5 questions