Re: [BUG] sched/fair: divide error in __calc_prop_weight() from the enqueue path (flat-hierarchy series)

Jake Steinman <[email protected]>
Newsgroups org.kernel.vger.cgroups,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.