Start here
Runqueue vs wait queue
Per-CPU runqueues reduce lock contention: each core mostly schedules its own runnable set. When a thread blocks in a syscall, it leaves the runqueue and joins a wait queue tied to an object (pipe buffer, futex, disk request). Wakeups return it to runnable.
By the end of this page you should be able to
- Contrast runqueue membership with wait-queue membership.
- Explain why “one global queue” is usually not how Linux works.
- Name one reason a runnable task might still not get CPU time immediately.
Operating systems · Processes
Process scheduling queues
Runqueues, waitqueues, and why “scheduling” is plural
TL;DR
The OS keeps **runnable** tasks on per-CPU runqueues (policy-dependent) while **blocked** tasks sit on wait queues keyed by events (I/O completion, futex, pipe data). Scheduling moves tasks between these structures, confusing them loses interview points.
Summary
Scheduling queues encode the work the OS must do to be fair and responsive. Debugging “slow app” often means identifying whether delay is runqueue wait, lock wait, or I/O wait.
Deeper narrative
Runqueues hold runnable entities; wait queues hold blocked ones. I/O completion moves tasks between them. CFS uses a red-black tree keyed by vruntime; RT classes use priority lists, know both textbook MLFQ and Linux reality.
Mechanism (step by step)
Admission
Fork/ wakeup enqueues on appropriate CPU runqueue (respecting affinity).
Dispatch
Scheduler tick or blocking syscall triggers `schedule()`.
Blocking
Task removed from runqueue, placed on wait queue with condition.
Wakeup
IRQ or completion moves task back to runnable; wake_affine chooses CPU.
Key insights
Runnable vs blocked
Wake_one vs wake_all
Priority inversion ties queues
Runqueue length ≠ load average nuance
Did you know?
Common pitfalls
Thinking one global queue
Per-CPU runqueues reduce lock contention; balancing introduces migration cost.
Ignoring throttling
CFS bandwidth and cgroup cpu.max can make tasks appear “runnable” but not scheduled.
Glossary
Runqueue
Wait queue
vruntime
Interview follow-ups
- Difference between runqueue and wait queue?
- Why might a task bounce between CPUs excessively?
- How does `SCHED_IDLE` differ from nice 19?
Callouts
Tooling
`perf sched`, `latencytop` (where available), and `trace-cmd` visualize wait-for-CPU vs sleep.
Walkthrough & deep dive
Left: practical “how would I use this?” threads. Right: slower, code-leaning explanations, open one panel at a time so the page does not feel like a wall of sameness.
Walkthrough
Diagram
Deep dive
Per-CPU ksoftirqd
Network-heavy workloads can spend time in softirq context, shows why CPU “idle” is not simple.
Scheduler latency snapshot
perf sched record -- sleep 1perf sched latency 2>/dev/null | head
Self-check
1A thread blocked on a pipe read is typically…
2Runqueues primarily hold…
3Thundering herd relates to…