ยง8.1โ€“8.2MLFQ: Basic Rules โ€ฆ Attempt #1: How To Change Priority

Part I OSTEP pp. 77โ€“82 ยท ~6 min read

  • mlfq
  • starvation
  • gaming

Chapter 7 ended with an impossible-sounding demand: SJF-like turnaround and RR-like response, with zero advance knowledge of job lengths. The answer is one of the most famous schedulers ever built โ€” the Multi-Level Feedback Queue , first described by Corbatรณ et al. in 1962 for the Compatible Time-Sharing System (CTSS); that work (plus Multics) earned Corbatรณ the Turing Award, and refined MLFQs run inside BSD derivatives, Solaris, and Windows to this day.

The Crux: How To Schedule Without Perfect Knowledge?

How can we design a scheduler that minimizes response time for interactive jobs while also minimizing turnaround time, without a priori knowledge of job length?

Tip: Learn from history

MLFQ is a system that uses the past to predict the future โ€” like hardware branch predictors and caching algorithms. Such approaches work when behavior has phases and is therefore predictable; but beware โ€” learned predictions can be wrong, and drive a system to decisions worse than knowing nothing at all.

8.1 MLFQ: Basic Rules

MLFQ keeps a number of distinct queues, each with a priority level; a ready job sits on exactly one of them. Higher queue runs first; ties share via round robin:

THE RULES SO FAR

  • Rule 1: If Priority(A) > Priority(B), A runs (B doesnโ€™t).
  • Rule 2: If Priority(A) = Priority(B), A & B run in round robin.

The heart of MLFQ is that priority is not fixed โ€” it varies with observed behavior. Relinquish the CPU constantly while waiting for keyboard input? You look interactive; priority stays high. Grind the CPU for long stretches? Priority sinks. History becomes prediction:

[High Priority][Low Priority]Q8Q7Q6Q5Q4Q3Q2Q1ABCDWith only Rules 1โ€“2, A and B alternate slices forever;C and D never run at all โ€” an outrage!

Figure 8.1: a snapshot of the queues. The static picture is exactly what MLFQ is not about โ€” everything interesting is in how jobs move between queues over time.

8.2 Attempt #1: How To Change Priority

Remember the workload mix: short interactive jobs that relinquish the CPU often, and long CPU-bound jobs where response time doesnโ€™t matter. First attempt at priority adjustment:

ATTEMPT #1

  • Rule 3: When a job enters the system, it is placed at the highest priority (topmost queue).
  • Rule 4a: If a job uses up an entire time slice while running, its priority is reduced (down one queue).
  • Rule 4b: If a job gives up the CPU before the slice is up, it stays at the same level.

Example 1 โ€” a single long-running job descends and settles:

Figure 8.2: a single long-running job descends the queues (3 queues, 10 ms slices)
Aarrrun
Q2A @ Q2: 0โ€“10AQ1A @ Q1: 10โ€“20AQ0A @ Q0: 20โ€“200A0306090120150180
jobarrivalruntimeturnaroundresponse
A02002000
average200.000.00

The job enters at the top (Q2), burns a full 10 ms slice there (Rule 4a: demoted), another at Q1, and settles at Q0 for the rest of its 200 ms. A CPU-grinder proves itself long, and sinks.

Example 2 โ€” along came a short job. Here is the SJF approximation in action. Since MLFQ canโ€™t know whether a job is short, it assumes it might be (top priority on entry). Truly short jobs finish before sinking; long ones prove themselves long and drift down:

Figure 8.3: along came a short job โ€” MLFQ approximating SJF
AarrrunBarrrun
Q2A @ Q2: 0โ€“10AB @ Q2: 100โ€“110BQ1A @ Q1: 10โ€“20AB @ Q1: 110โ€“120BQ0A @ Q0: 20โ€“100AA @ Q0: 120โ€“200A0306090120150180
jobarrivalruntimeturnaroundresponse
A01802000
B10020200
average110.000.00

A has sunk to Q0 by the time B arrives at t=100. B enters at Q2 (Rule 3), instantly preempts A (Rule 1), and โ€” being only 20 ms โ€” completes within two slices, never reaching the bottom. A then resumes. Try making B longer: it stops being "short" and sinks like A did.

Example 3 โ€” what about I/O? Rule 4bโ€™s purpose: an interactive job doing constant I/O (keyboard, mouse) gives up the CPU early, and is not penalized:

Figure 8.4: a mixed I/O-intensive + CPU-intensive workload (Rule 4b at work)
Q2A @ Q2: 0โ€“10AB @ Q2: 10โ€“11B @ Q2: 20โ€“21B @ Q2: 30โ€“31B @ Q2: 40โ€“41B @ Q2: 50โ€“51B @ Q2: 60โ€“61B @ Q2: 70โ€“71B @ Q2: 80โ€“81B @ Q2: 90โ€“91B @ Q2: 100โ€“101B @ Q2: 110โ€“111B @ Q2: 120โ€“121B @ Q2: 130โ€“131B @ Q2: 140โ€“141B @ Q2: 150โ€“151B @ Q2: 160โ€“161B @ Q2: 170โ€“171B @ Q2: 180โ€“181Q1A @ Q1: 11โ€“20AA @ Q1: 21โ€“30AA @ Q1: 31โ€“40AA @ Q1: 41โ€“50AA @ Q1: 51โ€“60AA @ Q1: 61โ€“70AA @ Q1: 71โ€“80AA @ Q1: 81โ€“90AA @ Q1: 91โ€“100AA @ Q1: 101โ€“110AA @ Q1: 111โ€“120AA @ Q1: 121โ€“130AA @ Q1: 131โ€“140AA @ Q1: 141โ€“150AA @ Q1: 151โ€“160AA @ Q1: 161โ€“170AA @ Q1: 171โ€“177AQ0DiskB I/O: 10โ€“1800306090120150180
jobarrivalruntimeturnaroundresponse
A01601770
B01818110
average179.005.00

B computes 1 ms, issues an I/O, and repeats โ€” always releasing the CPU before its slice expires, so Rule 4b keeps it at Q2 forever. A grinds away at Q0 during every one of B's I/Os. Interactive feel for B, progress for A.

Problems with our current MLFQ

It looks good โ€” long jobs share the CPU, short and I/O-bound jobs run promptly. But attempt #1 has serious flaws (the book invites you to think deviously first):

  1. Starvation : with โ€œtoo manyโ€ interactive jobs at the top, long-running jobs at the bottom get zero CPU. They starve.
  2. Gaming the scheduler : run for 99% of your slice, then issue a throwaway I/O. Rule 4b keeps you at top priority with ~99% of the CPU โ€” a near-monopoly, by design(!).
  3. Behavior change: a CPU-bound job that becomes interactive is stranded at the bottom; nothing in the rules lets it climb back up.

Tip: Scheduling must be secure from attack

A scheduling policy might not look like a security concern โ€” but in a modern datacenter, where strangers share CPUs, memory, networks, and storage, a policy that can be gamed lets one user harm everyone else. Scheduling policy is part of a systemโ€™s security, and must be built accordingly. (The next sectionโ€™s fixes are exactly that.)

Two fixes coming: a periodic priority boost for starvation and phase changes, and honest accounting for the gamers.

Check yourself

1.MLFQ must deliver SJF-like turnaround without knowing job lengths. What replaces the missing oracle?

2.In Figure 8.3, B (20 ms) arrives at t=100 while A grinds at Q0. Why does B run immediately, and why does it never reach Q0?

3.What is Rule 4b's intent โ€” and its dark side?

4.Predict: ten I/O-happy interactive jobs churn at Q2 indefinitely. What happens to a long-running job at Q0 under attempt #1?

4 questions