Re: [PATCH 6/6 v3] sched/eevdf: Speedup short slice task scheduling

From: Peter Zijlstra

Date: Fri Jun 26 2026 - 02:41:53 EST


On Fri, Jun 26, 2026 at 09:27:41AM +0530, K Prateek Nayak wrote:
> Hello Peter,
>
> On 6/26/2026 3:58 AM, Peter Zijlstra wrote:
> > +static u64 ineligible_vruntime(struct cfs_rq *cfs_rq)
> > +{
> > + struct sched_entity *curr = cfs_rq->curr;
> > + long weight = cfs_rq->sum_weight;
> > + s64 delta = 0;
> > +
> > + if (curr && !curr->on_rq)
> > + curr = NULL;
> > +
> > + /*
> > + * This is called from set_next_task_fair(.first=true) /
> > + * set_protect_slice() so curr had better be set and on_rq.
> > + */
> > + WARN_ON_ONCE(!curr);
>
> set_protect_slice() is indeed called from set_next_entity(.first=true)
> but it is done after __dequeue_entity() and before "cfs_rq->curr" is
> set (both sched/flat and sched/core have the same pattern).
>
> You should be hitting this splat very easily unless you have moved
> set_protect_slice() after the setting of cfs_rq->curr in your tree.


| static void set_next_task_fair(struct rq *rq, struct task_struct *p, bool first)
| {
| struct sched_entity *se = &p->se;
| bool throttled = false;
| struct cfs_rq *cfs_rq = &rq->cfs;
| unsigned long weight = NICE_0_LOAD;
| bool on_rq = se->on_rq;
|
| clear_buddies(cfs_rq, se);
|
| if (on_rq)
| __dequeue_entity(cfs_rq, se);

XXX

|
| for_each_sched_entity(se) {
| cfs_rq = cfs_rq_of(se);
|
| if (!IS_ENABLED(CONFIG_FAIR_GROUP_SCHED) ||
| !first || !cfs_rq->h_curr)
| set_next_entity(cfs_rq, se);
|
| /* ensure bandwidth has been allocated on our new cfs_rq */
| throttled |= account_cfs_rq_runtime(cfs_rq, 0);
|
| if (on_rq)
| weight = __calc_prop_weight(cfs_rq, se, weight);
| }
|
| if (throttled)
| task_throttle_setup_work(p);
|
| se = &p->se;
| cfs_rq->curr = se;

XXX

|
| if (on_rq) {
| reweight_eevdf(cfs_rq, se, weight, se->on_rq);
| if (first)
| set_protect_slice(cfs_rq, se);

XXX

| }
|
| if (task_on_rq_queued(p)) {
| /*
| * Move the next running task to the front of the list, so our
| * cfs_tasks list becomes MRU one.
| */
| list_move(&se->group_node, &rq->cfs_tasks);
| }
| if (!first)
| return;
|
| WARN_ON_ONCE(se->sched_delayed);
|
| if (hrtick_enabled_fair(rq))
| hrtick_start_fair(rq, p);
|
| update_misfit_status(p, rq);
| sched_fair_update_stop_tick(rq, p);
| }


Is what it looks like here. Anyway, let me actually build it and try ;-)