kernel/sched/loadavg.c | 2 +- kernel/sched/sched.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
Linus,
please pull the latest sched/urgent branch from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-urgent-2025-07-20
up to: 36569780b0d6: sched: Change nr_uninterruptible type to unsigned long
A single fix for the scheduler. A recent commit changed the runqueue
counter nr_uninterruptible to an unsigned int. Due to the fact that the
counters are not updated on migration of a uninterruptble task to a
different CPU, these counters can exceed INT_MAX. The counter is cast to
long in the load average calculation, which means that the cast expands
into negative space resulting in bogus load average values. Convert it back
to unsigned long to fix this.
Thanks,
tglx
------------------>
Aruna Ramakrishna (1):
sched: Change nr_uninterruptible type to unsigned long
kernel/sched/loadavg.c | 2 +-
kernel/sched/sched.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c
index c48900b856a2..52ca8e268cfc 100644
--- a/kernel/sched/loadavg.c
+++ b/kernel/sched/loadavg.c
@@ -80,7 +80,7 @@ long calc_load_fold_active(struct rq *this_rq, long adjust)
long nr_active, delta = 0;
nr_active = this_rq->nr_running - adjust;
- nr_active += (int)this_rq->nr_uninterruptible;
+ nr_active += (long)this_rq->nr_uninterruptible;
if (nr_active != this_rq->calc_load_active) {
delta = nr_active - this_rq->calc_load_active;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 475bb5998295..83e3aa917142 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1149,7 +1149,7 @@ struct rq {
* one CPU and if it got migrated afterwards it may decrease
* it on another CPU. Always updated under the runqueue lock:
*/
- unsigned int nr_uninterruptible;
+ unsigned long nr_uninterruptible;
union {
struct task_struct __rcu *donor; /* Scheduler context */
The pull request you sent on Sun, 20 Jul 2025 14:04:59 +0200 (CEST): > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-urgent-2025-07-20 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/62347e279092ae704877467abdc8533e914f945e Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
On Sun, 20 Jul 2025 at 05:05, Thomas Gleixner <tglx@linutronix.de> wrote: > > A single fix for the scheduler. A recent commit changed the runqueue > counter nr_uninterruptible to an unsigned int. Due to the fact that the > counters are not updated on migration of a uninterruptble task to a > different CPU, these counters can exceed INT_MAX. The counter is cast to > long in the load average calculation, which means that the cast expands > into negative space resulting in bogus load average values. Convert it back > to unsigned long to fix this. I've obviously pulled this, but considering that the thing isn't actually really an unsigned value in the first place, and all users seem to cast it to 'long' anyway, there's an obvious question... Why is it unsigned in the first place, rather than just make it be the more natural signed type? At that point, the _size_ of the type wouldn't even have mattered (outside of actual overflows, of course). Of course, regardless of all this, if it does negative due to migration, it looks like the calc_load_fold_active() calculations end up being a bit nonsensical. Not that it looks like that matters either, but it did make me go "Hmm - people seem to _assume_ it's always positive, it has a _type_ that is always positive, but then we have those odd hacks for the fact that it can actually be negative". So none of this seems to _matter_ (outside of the "unsigned int got *really* mangled" issue that this pull fixes), but it's all a bit odd. Linus
On Sun, Jul 20, 2025 at 11:20:31AM -0700, Linus Torvalds wrote: > I've obviously pulled this, but considering that the thing isn't > actually really an unsigned value in the first place, and all users > seem to cast it to 'long' anyway, there's an obvious question... Why > is it unsigned in the first place, rather than just make it be the > more natural signed type? Histerical raisins AFAIU. I think the original reason to make the thing unsigned was to get the 2s complement wrapping behaviour. Yes, these days we have -fwrapv and everybody knows signed types wrap properly too (although Kees will argue signed should not wrap etc..). But back then who knows.
© 2016 - 2025 Red Hat, Inc.