skip to content

EEVDF is not just a better CFS

category: Kerneldate: 1 min read
difficulty: Advancedsetup: 0 minprereqs: Linux, C, Scheduling concepts
#kernel#scheduler#linux#eevdf#cfs

The kernel's EEVDF scheduler replaced CFS in 6.6. Most writeups frame it as "a fairer CFS". That undersells it. EEVDF redefines what "fair" means — from proportional time to proportional lag — and that changes the right answer for latency-bound services.

The mental model shift

CFS tracked virtual runtime: a monotonic, weight-normalized notion of how much CPU a task has consumed. EEVDF tracks lag — the signed difference between what a task was entitled to and what it actually received. Eligibility becomes a per-task, per-interval question, not a global ordering.

C
/* simplified from kernel/sched/fair.c */
static s64 entity_lag(struct sched_entity *se, u64 avruntime) {
s64 vlag = se->vlag;
/* lag normalized against the scheduling period */
vlag -= sign(vlag) * min(abs(vlag), avruntime - se->vruntime);
return vlag;
}

What this means for you

  • nice is no longer a smooth dial. It interacts with latency-nice.
  • Tail latency on mixed workloads improves even when average doesn't.
  • Pin your latency-sensitive task with latency-nice=-20, not just nice.

A scheduler is a policy engine that runs a billion times a second. Every heuristic you remove is a bug you never write.

If you operate latency-bound services, re-benchmark against 6.6+. The numbers move in directions that surprised me, mostly for the better.