Test yourself · category 14 of 20
Physical memory, sbrk and page faults
The kalloc free list and kmem.lock, junk fills and who zeroes pages, eager sbrk versus lazy sbrklazy, and how vmfault turns a page fault into a page or a kill.
In this build the kernel image ends at end = 0x80020bb0, and PHYSTOP is
0x88000000. How many pages does freerange put on the free list at boot?
Right after kinit, which physical page does the first kalloc return (it becomes
the root of the kernel page table)?
kalloc fills each page it hands out with 0x05 bytes instead of zeros, even though
many callers then zero it themselves. Why?
A program calls sbrklazy(4096). Click the line in sys_sbrk that is the entire
allocation work the kernel does for it.
Your pick: none yet (click a line in the code)
kalloc returns pages full of 0x05 junk. Which of these functions zero the page
they get from kalloc before using it?
Click the line in vmfault that makes a user-mode store to the stack’s
guard page fatal instead of quietly supplying a new page.
Your pick: none yet (click a line in the code)
After sbrklazy(1 << 30), usertests stores to 0x13000, a page that is not mapped
yet. Put the events in order.
- usertrap sees scause 15 and calls vmfault with p->sz and stval
- The store finds a level-0 PTE with V clear and raises a store page fault: scause 15, stval 0x13000
- userret installs the user page table between two sfence.vma and executes sret
- vmfault checks 0x13000 < sz and that the page is not mapped, then kallocs, zeroes and maps it R W U
- uservec saves the user registers in the trapframe and switches satp to the kernel page table
- The same store executes again, since sepc was not advanced, and succeeds
A process takes a page fault on a lazily allocated heap page. usertrap calls
vmfault, which calls kalloc, which has just acquired kmem.lock. What is the
state of this hart?
True or false: after sbrk(-8192) frees two pages, xv6 must flush them from the TLB,
but it forgets to, so the program could still reach the freed pages through stale TLB
entries.
Why?
In our run, the usertests child running lazy_alloc had p->sz = 0x12000 when it
called sbrklazy(1 << 30). It then stores to 0x13000, 0x53000, … , every 64 pages,
4096 stores in all. Besides the 4096 data pages, how many page-table pages does
walk allocate during these faults?
A process with p->sz = 0x5000 calls sbrk(65536) and it succeeds. What does
sbrk return?
kexec maps the user stack’s guard page and then clears its PTE_U, instead of
simply leaving the page unmapped. In this kernel, why does that difference matter?
A process has p->sz = 0x5000 (page-aligned, nothing mapped above it). It calls
sbrk(1) and then sbrk(1) again, both eager. How many physical pages does
uvmalloc allocate in total across the two calls?
A process has p->sz = 0x5000 (page-aligned, nothing mapped above it). It calls
sbrklazy(1), then, as its very next memory access above 0x5000, stores a byte at
0x5800. What happens?
Which of these functions can call vmfault to allocate a lazily promised page?
A program grows its memory with sbrklazy, writes machine code into the new region
(which faults the page in), and then jumps to it. What happens at the jump?
True or false: kalloc returns a page filled with zeros.
Why?
Match each function with what it writes into a physical page it has just freed or obtained.
Imagine kmem.lock were removed. Hart 1 in kalloc reads the head (A); then hart 2
runs a complete kfree(P); then hart 1 stores A->next (B) as the new head. What is
the result?
Which of these calls make kfree panic? (In this build end = 0x80020bb0 and
PHYSTOP = 0x88000000.)
A program calls sbrklazy(-8192) to give back two pages. What does sys_sbrk do?
The shell’s child has p->sz = 0x5000 and its whole memory is mapped through a single
level-0 page-table page. malloc calls sbrk(65536) (eager). How many times is
kalloc called during that system call?
Physical memory is nearly exhausted. How does running out show up to a program that grew
with eager sbrk, compared with one that used sbrklazy?
Right after exec, the level-0 PTE for sh’s page at 0x3000 (just below its one
stack page) read 0x21fce407 in our run. Decode it.
Value: 0x21fce407