xv6, line by line
lab 7
Lab 77 A sampling profiler

Lab 7 · reveal · 19 steps · 8 commits

A sampling profiler: the reference solution

Where does a program spend its time? A sampling profiler answers without changing the program: every so often, it stops the program, writes down where it was, and lets it go on. After a few hundred samples, the places that come up most are the places where the time goes. In this lab you build one for xv6. A process asks the kernel to sample it, the kernel counts the interrupted program counters in a histogram of address buckets, and a new command, prof grep ..., prints the hottest functions of any program.

The hardware already stops every program ten times a second: the timer interrupt that drives the scheduler. The design questions are about using that interrupt well. Which piece of code sees every tick on every hart, and which register says where the program was? Where should a histogram live, who may touch it while an interrupt handler is updating it, and what happens to it across fork, exec and exit? A program run under the profiler does not know it is being profiled: how do the samples get out? And when you point the same machinery at the kernel itself, what can it see, and what is it structurally unable to see?

The reference solution is eight small commits. It finds the inner loop of grep’s regular expression matcher from 61 samples, and its kernel profile of usertests turns up a surprise about which kernel code a timer-driven profiler can see at all.

Each step shows one change on the branch ext/07-profiler, the code around it, and the state of the machine when that code runs.

The route
  1. 1A histogram that fills exactly one page kernel/prof.h
  2. 2Two entries in the system-call table kernel/syscall.c
  3. 3profile allocates a page and fills in the header kernel/prof.c
  4. 4A field in the private part of struct proc kernel/proc.h
  5. 5freeproc frees the page and clears the pointer kernel/proc.c
  6. 6The sample, in usertrap, before yield kernel/trap.c
  7. 7Counting one sample kernel/prof.c
  8. 8Why not in clockintr kernel/trap.c
  9. 9profget copies the page out kernel/prof.c
  10. 10kexit writes the profile while it still can kernel/proc.c
  11. 11The write itself is ordinary file-system code kernel/prof.c
  12. 12A test with a hot loop it can find user/proftest.c
  13. 13prof finds the command's text and runs it profiled user/prof.c
  14. 14Symbol files on the disk Makefile
  15. 15kerneltrap feeds the kernel profile kernel/trap.c
  16. 16Three harts, one histogram, one lock kernel/prof.c
  17. 17One kernel profile at a time kernel/prof.c
  18. 18usertrap leaves a kernel profile alone kernel/trap.c
  19. 19Where the critical sections went kernel/spinlock.c

Keys: ← → step · Home start