The default core-sched ordering runs the longest waiting task first by comparing p->scx.core_sched_at stamps. The stamp is maintained under two rules. touch_core_sched() stamps when a task starts waiting for a CPU and when its slice runs out. If the scheduler implements ops.core_sched_before(), touch_core_sched_dispatch() re-stamps on every dispatch. A comparison can see one stamp taken under each rule, which isn't a meaningful ordering. The dispatch rule also buys little - it only aligns bypass-mode comparisons with the local DSQ order. Multiple schedulers make the mixed comparisons more common. Wait time is what p->scx.runnable_at already tracks for the stall watchdog. Delete core_sched_at with both touch functions and compare runnable_at in the scx_prio_less() fallback. runnable_at is refreshed only on enqueue and goes stale while a task keeps occupying its CPU. Instead of re-stamping, order a running task after every waiting task as it is the most recently serviced.
Showing the changes to include (1 of 2 files). Show all
Unified · Split
| @@ -212,9 +212,6 @@ struct sched_ext_entity { · 211 unmodified lines | ||
| 212 | 212 | struct list_head runnable_node; /* rq->scx.runnable_list */ |
| 213 | 213 | unsigned long runnable_at; |
| 214 | 214 | |
| 215 | −#ifdef CONFIG_SCHED_CORE | |
| 216 | − u64 core_sched_at; /* see scx_prio_less() */ | |
| 217 | −#endif | |
| 218 | 215 | #ifdef CONFIG_EXT_SUB_SCHED |
| 219 | 216 | unsigned long rescue_at; /* queued on a rescue DSQ at, jiffies */ |
| 220 | 217 | #endif |