Re: [BUG] sched/fair: divide error in __calc_prop_weight() from the enqueue path (flat-hierarchy series)
From: Jake Steinman
Date: Wed Aug 19 2026 - 09:23:22 EST
Hi Prateek,
> Was your laptop suspended at that point?
No -- awake, but it had been through a suspend/resume cycle earlier in
the same boot. From the journal of the boot that died:
15:32:43 Lid closed
15:32:44 PM: suspend entry (s2idle)
16:25:55 Lid opened
16:25:55 PM: suspend exit
16:42:54 Lid closed
20:17:49 Lid opened
20:31:59 Lid closed
21:10:16 <last log line -- crash>
So the s2idle cycle ended 4h44m before the fault. At 21:10 the lid had
been shut for ~38 minutes, but the machine was on AC with
LidAction=TurnOffScreen, so it was awake with the display off, not
suspended -- the wallpaper daemon was still rendering once a minute
right up to the final log line, and the fork that tripped the divide
happened then.
Also relevant to the freeze_secondary_cpus() angle: that boot logged
zero CPU hotplug events. No smpboot lines, no "Disabling non-boot CPUs".
Caveat: s2idle's freeze path may not log at my loglevel, so I would not
read that as proof it never happened -- only that nothing surfaced.
> I think your current instrumentation from "Proposed guard" is good
> enough to tell where the problem is if it reproduces. Are you running
> with it on your setup currently?
Yes. All three hunks have been in the running kernel since 2026-08-18,
now on 7.2.0. Current status:
7.2.0-1, 17.3 h uptime with the guards in
"sched: tg_cpus() == 0, empty cpuset" -- 0 hits
"sched: cfs_rq->load.weight == 0" -- 0 hits
So nothing has reproduced yet. Given the original took 11.7 h of mostly
idle uptime to hit once and has not recurred in the days since, I read
17 h of silence as "not yet", not as evidence against the cpuset route.
I will report either way -- and if the tg_cpus() WARN is the one that
fires, that settles the mechanism on the spot.
I have sent the tg_cpus() floor as a separate patch per Peter's request.
I deliberately kept it to that one hunk: with tg_cpus() floored and
tg_tasks() already flooring at 1, nr >= 1, so shares_max >= tg_shares
and the inverted clamp in __calc_smp_shares() becomes unreachable. The
other two hunks are belt-and-braces and I did not want to bundle them
into something Peter offered to take on symmetry grounds.
@Guopeng: thanks, the isolcpus=domain reproducer is interesting. I am
not using isolcpus here and have no domain isolation configured, so my
case is not that exact path, but if you want a second machine to test
either of your series on I am happy to run them -- this box reproduces
suspend/resume cycles all day and has 16 CPUs with a P/E/LP-E split,
which may be a useful shape for hotplug edge cases.
Thanks,
Jake