From nobody Sun Feb 8 22:21:42 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 329CB39900A; Thu, 5 Feb 2026 15:09:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770304149; cv=none; b=VI2SbKunvB9C8tr/vpWULB3jD0Yn0gtXJYGfQJQ8B+PgH/S8L1+uH+ZwZ4i8TxAoDu/4QBreKWqTkEJahYyc1dNykDluF8lrbdU/ldcaTi9UnkhNpJUaHbAR/qlPFlxoec1yMhk8bqHpiExVxBdL+2JU5RlwsCbMd1u3f/XL9Z4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770304149; c=relaxed/simple; bh=K2EVgGdoi4y2PT+Y9ctngywJVj8QdCcBShw16+ochMM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K3TJyu7quooDvUIOiVWaqIclBGcMDV5OSBtxX0hUpQd6+yQcw7R9siNUQ1Rf0emkgY/EjflnjIwFRrroYhKYretUZHUWUi9d4472ZT6P9Ce1YoCgW97ptWtc8arOq+sSYOBIxv3lHphQ7/XOgCzTFYG3fJpl+MqgjQHCJm2OQ+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3A5491516; Thu, 5 Feb 2026 07:09:02 -0800 (PST) Received: from e135073.arm.com (unknown [10.57.8.39]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 27F0B3F778; Thu, 5 Feb 2026 07:09:04 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Christian Loehle , Pierre Gondois , stable@vger.kernel.org, Vincent Guittot , Ingo Molnar , Peter Zijlstra , Juri Lelli , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , Rik van Riel Subject: [PATCH 1/2] sched/fair: Fix integer underflow Date: Thu, 5 Feb 2026 16:08:44 +0100 Message-ID: <20260205150846.1242134-2-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260205150846.1242134-1-pierre.gondois@arm.com> References: <20260205150846.1242134-1-pierre.gondois@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" (struct sg_lb_stats).idle_cpus is of type 'unsigned int'. (local->idle_cpus - busiest->idle_cpus) can underflow to UINT_MAX for instance, and max_t(long, 0, UINT_MAX) will output UINT_MAX. Use lsub_positive() instead of max_t(). Fixes: 16b0a7a1a0af ("sched/fair: Ensure tasks spreading in LLC during LB") cc: stable@vger.kernel.org Signed-off-by: Pierre Gondois Reviewed-by: Vincent Guittot --- kernel/sched/fair.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index da46c31645378..aa14a9982b9f1 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -11249,8 +11249,8 @@ static inline void calculate_imbalance(struct lb_en= v *env, struct sd_lb_stats *s * idle CPUs. */ env->migration_type =3D migrate_task; - env->imbalance =3D max_t(long, 0, - (local->idle_cpus - busiest->idle_cpus)); + env->imbalance =3D local->idle_cpus; + lsub_positive(&env->imbalance, busiest->idle_cpus); } =20 #ifdef CONFIG_NUMA --=20 2.43.0 From nobody Sun Feb 8 22:21:43 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 05CB039900A for ; Thu, 5 Feb 2026 15:09:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770304153; cv=none; b=hAZ4GIkLVz+sowTXxMpAPGWSo/LJiicXeO51hzHV5nb6wwi0HkZb+iLPYccdpXZc2zzLLBfWK4GWrBN78Hgidu73FR4ysB664mRtwBXRiJ0zuRY9Mp9p7dOJrNOjAid84pEfwt2HfLb/ciaMHJpH/qJ44KduIcinmd0SF1Sa7QU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770304153; c=relaxed/simple; bh=K/SHd687WE1MGUP53kFvfAgRdHWx1I9y8XYLJmxNzt4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ju5Mk02iHK1+QpAlrk8uwZCnwlK+Q/Er3XWaTm0yFI7/LfGyi3AOOeUdRCXkzFFQMzgv57TG346GeQ2ba/LurEquQwWvTzVMQXQ/0hXqL+uFsP+YwvrWkb3RvzsQuRMn2jyxUo9xLOPv5dPrSwQEzww6N+U4wJos0eAkCyGwmB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1DCFC1576; Thu, 5 Feb 2026 07:09:06 -0800 (PST) Received: from e135073.arm.com (unknown [10.57.8.39]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5816F3F778; Thu, 5 Feb 2026 07:09:09 -0800 (PST) From: Pierre Gondois To: linux-kernel@vger.kernel.org Cc: Christian Loehle , Pierre Gondois , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , Rik van Riel Subject: [PATCH 2/2] sched/fair: Balance #Tasks/#CPUs if busiest group has no idle CPU Date: Thu, 5 Feb 2026 16:08:45 +0100 Message-ID: <20260205150846.1242134-3-pierre.gondois@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260205150846.1242134-1-pierre.gondois@arm.com> References: <20260205150846.1242134-1-pierre.gondois@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Balancing the number of idle CPUs between groups is done if: - the busiest group is overloaded: sum_nr_running > #CPUs - the local group has spare capacity: sum_nr_running <=3D #CPUs To avoid pulling too many tasks and moving the imbalance to the local group, the number of task pulled is half of: (local->idle_cpus - busiest->idle_cpus) Halving the imbalance currently lead to the following scenario. On a Juno with 2 clusters: CLU0: 4 CPUs and CLU1: 2 CPUs, with 6 long running tasks: - 1 task on the 2-CPUs cluster - 5 Tasks run in the 4-CPUs cluster Running the load balancer from the idle CPU (in CLU1): - Local group: CLU1: idle_cpus=3D1; nr_running=3D1; type=3Dgroup_has_spare - Busiest group: CLU0 idle_cpus=3D0; nr_running=3D5 type=3Dgroup_overloaded Half of (local->idle_cpus - busiest->idle_cpus) is 0. No task is migrated and the task placement persists. Balancing number of idle CPUs is only relevant if the busiest group has idle CPUs. Otherwise it is better to have an equal ratio of #tasks / #CPUs. sibling_imbalance() was also introduced to cope with groups with asymmetric sizes. This is also the case here. commit 7ff1693236f5 ("sched/fair: Implement prefer sibling imbalance calculation between asymmetric groups") Try to stay conservative and only balance the ratio of #Tasks / #CPUs if the busiest group has no idle CPUs. Note that a similar check present in update_pick_idlest() is not updated. Signed-off-by: Pierre Gondois --- kernel/sched/fair.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index aa14a9982b9f1..9dac3536d9c19 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -11235,20 +11235,18 @@ static inline void calculate_imbalance(struct lb_= env *env, struct sd_lb_stats *s return; } =20 - if (busiest->group_weight =3D=3D 1 || sds->prefer_sibling) { + env->migration_type =3D migrate_task; + if (busiest->group_weight =3D=3D 1 || sds->prefer_sibling || !busiest->i= dle_cpus) { /* - * When prefer sibling, evenly spread running tasks on - * groups. + * When prefer sibling, or when busiest has no idle CPU, + * evenly spread running tasks on groups. */ - env->migration_type =3D migrate_task; env->imbalance =3D sibling_imbalance(env, sds, busiest, local); } else { - /* * If there is no overload, we just want to even the number of * idle CPUs. */ - env->migration_type =3D migrate_task; env->imbalance =3D local->idle_cpus; lsub_positive(&env->imbalance, busiest->idle_cpus); } --=20 2.43.0