On 28 Mar 2023 11:26:37 +0200 Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> > @@ -4878,22 +4878,55 @@ place_entity(struct cfs_rq *cfs_rq, stru > if (WARN_ON_ONCE(!load)) > load = 1; > lag = div_s64(lag, load); > + > + vruntime -= lag; > + } > + > + /* > + * Base the deadline on the 'normal' EEVDF placement policy in an > + * attempt to not let the bonus crud below wreck things completely. > + */ > + se->deadline = vruntime; > + > + /* > + * The whole 'sleeper' bonus hack... :-/ This is strictly unfair. > + * > + * By giving a sleeping task a little boost, it becomes possible for a > + * 50% task to compete equally with a 100% task. That is, strictly fair > + * that setup would result in a 67% / 33% split. Sleeper bonus will > + * change that to 50% / 50%. > + * > + * This thing hurts my brain, because tasks leaving with negative lag > + * will move 'time' backward, so comparing against a historical > + * se->vruntime is dodgy as heck. > + */ > + if (sched_feat(PLACE_BONUS) && > + (flags & ENQUEUE_WAKEUP) && !(flags & ENQUEUE_MIGRATED)) { > + /* > + * If se->vruntime is ahead of vruntime, something dodgy > + * happened and we cannot give bonus due to not having valid > + * history. > + */ > + if ((s64)(se->vruntime - vruntime) < 0) { > + vruntime -= se->slice/2; > + vruntime = max_vruntime(se->vruntime, vruntime); > + } > } > > - se->vruntime = vruntime - lag; > + se->vruntime = vruntime; > > /* > * When joining the competition; the exisiting tasks will be, > * on average, halfway through their slice, as such start tasks > * off with half a slice to ease into the competition. > */ > - if (sched_feat(PLACE_DEADLINE_INITIAL) && initial) > + if (sched_feat(PLACE_DEADLINE_INITIAL) && (flags & ENQUEUE_INITIAL)) > vslice /= 2; > > /* > * EEVDF: vd_i = ve_i + r_i/w_i > */ > - se->deadline = se->vruntime + vslice; > + se->deadline += vslice; > } Because lag makes no sense for more-than-a-second sleepers, it is simpler to make them able to preempt the current at the next tick, in line with what fork can do at best.