Re: [PATCH 09/12] sched_ext: Eject the top rescue consumer on overload
[email protected] Sat, 01 Aug 2026 09:11:14 +0000
| Newsgroups | dev.linux.lists.sched-ext |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(= s) to consider: - [Medium] The `time_before()` check in `scx_rescue_check_overload()` suffe= rs from a 32-bit jiffies wraparound vulnerability, disabling rescue overloa= d protection for 24.8-day intervals on systems with 32-bit `unsigned long`. -- --- Patch [9]: [PATCH 09/12] sched_ext: Eject the top rescue consumer on ov= erload --- commit 50e2ffc187a8450dacf680dcf11b98c2167b7621 Author: Tejun Heo <[email protected]> sched_ext: Eject the top rescue consumer on overload This patch tracks each scheduler's recent rescue consumption per CPU as a decaying average. If the oldest waiter on a CPU's rescue DSQ waits past a configured threshold, the sub-scheduler with the highest recent consumption is ejected. This prevents the generic stall watchdog from unfairly blaming the waiting task's owner instead of the misbehaving party. > diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c > index 3c1f11268e7f3..fdbe1c1bfaa8d 100644 > --- a/kernel/sched/ext/sub.c > +++ b/kernel/sched/ext/sub.c [ ... ] > @@ -434,6 +459,63 @@ static bool scx_rescue_try_admit(struct rq *rq, stru= ct task_struct *p) > return false; > } > =20 > +/** > + * scx_rescue_check_overload - Eject the top rescue consumer on a stuck = rescue > + * @rq: rq whose rescue timer fired > + * > + * If the oldest waiter on @rq's rescue DSQ has been queued for too long= , rescue > + * demand on this cpu persistently exceeds the configured bandwidth. Eje= ct the > + * sub with the highest recent rescue consumption instead of letting the > + * scheduler stall path blame the waiter's owner, who may just be crowde= d out. > + */ > +static void scx_rescue_check_overload(struct rq *rq) > +{ > + struct scx_sched *victim =3D NULL, *pos; > + struct task_struct *p; > + int cpu =3D cpu_of(rq); > + u64 max_avg =3D 0; > + u32 dur_ms; > + > + lockdep_assert_rq_held(rq); > + > + p =3D list_first_entry_or_null(&rq->scx.rescue.dsq.list, struct task_st= ruct, > + scx.dsq_list.node); > + if (!p) > + return; > + > + /* has the head waiter been queued for longer than the threshold? */ > + if (time_before(jiffies, p->scx.rescue_at + scx_rescue_overload_after)) > + return; > + > + /* > + * Grace period after the last ejection on this cpu - the freed > + * bandwidth gets one threshold's worth of time to drain the backlog > + * before another sub is judged. > + */ > + if (time_before(jiffies, rq->scx.rescue.kill_at + scx_rescue_overload_a= fter)) > + return; [Severity: Medium] Does this time_before() check have an issue with jiffies wraparound on 32-b= it systems? If no rescue ejection occurs for LONG_MAX jiffies (about 24.8 days at HZ=3D= 1000 on 32-bit systems), jiffies - rq->scx.rescue.kill_at will exceed LONG_MAX. Because the time_before() macro uses signed arithmetic, the difference wraps around to a negative value. This causes time_before() to incorrectly evaluate to true, falsely trapping the CPU in a continuous grace period. Would this disable overload ejections for the next 24.8 days and cause the scheduler to fall back to the generic stall watchdog instead? --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260801085150.2697= [email protected]?part=3D9