Β§21.4–21.7What If Memory Is Full? … Summary

Part I OSTEP pp. 235–238 Β· ~6 min read

  • page-replacement policy
  • swap daemon
  • watermarks

Servicing a fault assumed a free frame was waiting. Suppose none is.

21.4 What If Memory Is Full?

Then the OS must first page out one or more residents to make room β€” and choosing the victim is the page-replacement policy , a decision with terrifying stakes: evict the wrong page and a program runs at disk-like speeds instead of memory-like speeds β€” 10,000 to 100,000Γ— slower. That number is why the policy gets the entire next chapter; for now it’s enough that one exists, built on this chapter’s mechanisms.

21.5 Page Fault Control Flow

Everything the hardware can encounter on a reference, in one place β€” so when someone asks β€œwhat happens when a program fetches data from memory?”, you have the full answer. The hardware side (Figure 21.2):

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
    PTEAddr = PTBR + (VPN * sizeof(PTE))
    PTE = AccessMemory(PTEAddr)
    if (PTE.Valid == False)
        RaiseException(SEGMENTATION_FAULT)
    else
        if (CanAccess(PTE.ProtectBits) == False)
            RaiseException(PROTECTION_FAULT)
        else if (PTE.Present == True)
            TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
            RetryInstruction()
        else if (PTE.Present == False)
            RaiseException(PAGE_FAULT)
The three fates of a TLB miss, by PTE bits
validpresentoutcome
case 10(moot)RaiseException(SEGMENTATION_FAULT)
case 211TLB_Insert, retry β†’ hit
case 310RaiseException(PAGE_FAULT)
Dotted-underlined cells have explanations β€” click one.

And the OS side β€” the handler itself, seven lines that carry the whole illusion (Figure 21.3):

PFN = FindFreePhysicalPage()
if (PFN == -1)              // no free page found
    PFN = EvictPage()       // run replacement algorithm
DiskRead(PTE.DiskAddr, PFN) // sleep (waiting for I/O)
PTE.present = True          // update page table with present
PTE.PFN     = PFN           // bit and translation (PFN)
RetryInstruction()          // retry instruction

21.6 When Replacements Really Occur

Waiting until memory is entirely full before evicting is a little unrealistic. Real systems keep a cushion, governed by high and low watermarks and patrolled by a background thread β€” the swap daemon :

The watermark cycle: proactive eviction keeps the fault path out of the eviction business
60% freeHWLWfree physical pagesswap daemon: asleep πŸ’€

1Plenty free β€” the daemon sleeps

Free pages sit comfortably above the low watermark. Page faults are cheap-ish: the handler grabs a free frame directly, no eviction in sight. The background thread naps.

step 1 / 4

Aside: Daemon

Usually pronounced β€œdemon”: an old term for a background thread or process that does something useful. The source (once again!) is Multics β€” Corbató’s team borrowed it from Maxwell’s demon of thermodynamics, β€œan imaginary agent which helped sort molecules of different speeds and worked tirelessly in the background.”

Tip: Do Work In The Background

Batching work in the background pays repeatedly: disks schedule grouped writes better; applications see writes β€œcomplete” instantly; some work evaporates entirely (write a file, delete it β€” the disk never hears about it); and idle time gets used. File-write buffering and the swap daemon are the same idea wearing different hats.

21.7 Summary

More memory than physically exists: a present bit in the PTE, a page-fault handler that fetches from swap, and a policy (pending) for making room. The amazing part is that it all happens transparently β€” the process just accesses its private, contiguous virtual memory, never learning that its pages scatter across arbitrary frames or vanish to disk entirely. In the common case, a memory access is fast; in the worst case, one instruction takes multiple disk operations and many milliseconds β€” the hierarchy’s whole span, hidden inside a single load.

Homework (Measurement): vmstat + mem.c

Watch swapping happen: run vmstat 1 beside mem.c and track swpd/free as allocations grow; push past your RAM (mem 5000, 6000…) and watch si/so light up; measure the bandwidth cliff between fits-in-memory and constantly-swapping runs (make the graph!); find where allocation fails as swap itself (swapon -s) runs out. Get it at ostep-homework.

Check yourself

1.On a TLB miss, the hardware inspects the PTE. Name the three cases and their outcomes (Figure 21.2).

2.Reconstruct the page-fault handler's algorithm (Figure 21.3), in order.

3.Why don't operating systems wait until memory is completely full before evicting β€” and what governs the proactive approach?

4.The swap daemon evicts many pages at once. What extra performance trick does batching unlock?

5.The book warns that a bad page-replacement decision can make a program run 10,000–100,000Γ— slower. Where does that terrifying ratio come from?

5 questions