From nobody Mon May 25 00:09:07 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83E5D3EDAA7; Wed, 20 May 2026 08:35:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779266104; cv=none; b=OCSeact71B7WvDfFl/VybzIsgY1PcuySCylH5tjjSkmrkOaoGDqc4xyf5Yfaq4FgyvAVArZxaUDYkN5hXH052xC4Onzxo6+6+xezX+N11QDOwhoYeSGw7YTDKWKoxYY2sW1AabNcMcb7R3t5WUVNBHk+00hRcPXNn5dOiiw5HCo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779266104; c=relaxed/simple; bh=PBWYd2r1HbL7VNA/hlhhiIBdhwg8iOtGxSLKogFxp4w=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=gmJrCFB71ofH3CZlBFhXGPVQe4XsLx3iku1NtzmFlzmxC9r32+eLiKKNK9WUBvD+oZqUJVcLK+r+joLMESbn99TkrWyLnyEvfuF7CJb2PeIeG7hR+D+ahbeMFlfWoaLOJnLwiePl3EGboiW/wq2wbNn6HsKRfDBCQ94yArpwzTA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=KnxKfFqG; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=tSO1gMVc; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="KnxKfFqG"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="tSO1gMVc" Date: Wed, 20 May 2026 08:34:59 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1779266101; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/SsxjlvjkTgnGegQnSskufVRxs2NEy2liyFMoZQYEYs=; b=KnxKfFqGcd1GSMKhQd/9OavHzoVW9FOMfuFfoFkHUx2U0NvRDgsN2GN8jHoe91r9TOzYX0 3Rw607vdeNYA4HlZfoNn6Pkm10peOJLMqRPs/o6Iwtsju8zGkkjlpOgkaPRXUtHohvqRVS X7kj3GFcp0pKO2+h/apP5kiqlUf0Qy+tFozn7G/xIYbOf86xi5COwFeXohpIzMSq97/bn3 /8F82YjCe1nIRU5mjJzLoKoXHHYMoqS4ZBO7+LeBo2ADtK93bmwSMm95ed7jKpEB6Za9Gk wrybmYNQcQLW+6FaIKPVJHvPXCkbT1amZwq/ZDBBknOXzki0qmFnnU+WnLp3og== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1779266101; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/SsxjlvjkTgnGegQnSskufVRxs2NEy2liyFMoZQYEYs=; b=tSO1gMVcvDaweiLt4NedJFnbhmaEx2D25aom4vIDTJqlt8Ce/o3oLOTX3FVgfEZbzwbmdN QR3KvClMEWtRc4Cw== From: "tip-bot2 for Chen Yu" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: sched/core] sched/cache: Record per LLC utilization to guide cache aware scheduling decisions Cc: Chen Yu , Tim Chen , "Peter Zijlstra (Intel)" , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: =?utf-8?q?=3Ca48151b3d57f2a42a5971aaead1b7f81e69229f4=2E1775065?= =?utf-8?q?312=2Egit=2Etim=2Ec=2Echen=40linux=2Eintel=2Ecom=3E?= References: =?utf-8?q?=3Ca48151b3d57f2a42a5971aaead1b7f81e69229f4=2E17750653?= =?utf-8?q?12=2Egit=2Etim=2Ec=2Echen=40linux=2Eintel=2Ecom=3E?= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <177926609985.711.8714328350981285611.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the sched/core branch of tip: Commit-ID: f025ef275388742643a2c33f00a0d9c0af3112ee Gitweb: https://git.kernel.org/tip/f025ef275388742643a2c33f00a0d9c0a= f3112ee Author: Chen Yu AuthorDate: Wed, 01 Apr 2026 14:52:15 -07:00 Committer: Peter Zijlstra CommitterDate: Thu, 09 Apr 2026 15:49:48 +02:00 sched/cache: Record per LLC utilization to guide cache aware scheduling dec= isions When a system becomes busy and a process's preferred LLC is saturated with too many threads, tasks within that LLC migrate frequently. These in LLC migrations introduce latency and degrade performance. To avoid this, task aggregation should be suppressed when the preferred LLC is overloaded, which requires a metric to indicate LLC utilization. Record per LLC utilization/cpu capacity during periodic load balancing. These statistics will be used in later patches to decide whether tasks should be aggregated into their preferred LLC. Signed-off-by: Chen Yu Co-developed-by: Tim Chen Signed-off-by: Tim Chen Signed-off-by: Peter Zijlstra (Intel) Link: https://patch.msgid.link/a48151b3d57f2a42a5971aaead1b7f81e69229f4.177= 5065312.git.tim.c.chen@linux.intel.com --- include/linux/sched/topology.h | 4 ++- kernel/sched/fair.c | 70 +++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+) diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index 36553e1..159716f 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -68,6 +68,10 @@ struct sched_domain_shared { atomic_t nr_busy_cpus; int has_idle_cores; int nr_idle_scan; +#ifdef CONFIG_SCHED_CACHE + unsigned long util_avg; + unsigned long capacity; +#endif }; =20 struct sched_domain { diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a55ada2..6647d46 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -9992,6 +9992,28 @@ static inline int task_is_ineligible_on_dst_cpu(stru= ct task_struct *p, int dest_ return 0; } =20 +#ifdef CONFIG_SCHED_CACHE +static __maybe_unused bool get_llc_stats(int cpu, unsigned long *util, + unsigned long *cap) +{ + struct sched_domain_shared *sd_share; + + sd_share =3D rcu_dereference_all(per_cpu(sd_llc_shared, cpu)); + if (!sd_share) + return false; + + *util =3D READ_ONCE(sd_share->util_avg); + *cap =3D READ_ONCE(sd_share->capacity); + + return true; +} +#else +static inline bool get_llc_stats(int cpu, unsigned long *util, + unsigned long *cap) +{ + return false; +} +#endif /* * can_migrate_task - may task p from runqueue rq be migrated to this_cpu? */ @@ -10948,6 +10970,53 @@ sched_reduced_capacity(struct rq *rq, struct sched= _domain *sd) return check_cpu_capacity(rq, sd); } =20 +#ifdef CONFIG_SCHED_CACHE +/* + * Record the statistics for this scheduler group for later + * use. These values guide load balancing on aggregating tasks + * to a LLC. + */ +static void record_sg_llc_stats(struct lb_env *env, + struct sg_lb_stats *sgs, + struct sched_group *group) +{ + struct sched_domain_shared *sd_share; + int cpu; + + if (!sched_cache_enabled() || env->idle =3D=3D CPU_NEWLY_IDLE) + return; + + /* Only care about sched domain spanning multiple LLCs */ + if (env->sd->child !=3D rcu_dereference_all(per_cpu(sd_llc, env->dst_cpu)= )) + return; + + /* + * At this point we know this group spans a LLC domain. + * Record the statistic of this group in its corresponding + * shared LLC domain. + * Note: sd_share cannot be obtained via sd->child->shared, + * because the latter refers to the domain that covers the + * local group. Instead, sd_share should be located using + * the first CPU of the LLC group. + */ + cpu =3D cpumask_first(sched_group_span(group)); + sd_share =3D rcu_dereference_all(per_cpu(sd_llc_shared, cpu)); + if (!sd_share) + return; + + if (READ_ONCE(sd_share->util_avg) !=3D sgs->group_util) + WRITE_ONCE(sd_share->util_avg, sgs->group_util); + + if (unlikely(READ_ONCE(sd_share->capacity) !=3D sgs->group_capacity)) + WRITE_ONCE(sd_share->capacity, sgs->group_capacity); +} +#else +static inline void record_sg_llc_stats(struct lb_env *env, struct sg_lb_st= ats *sgs, + struct sched_group *group) +{ +} +#endif + /** * update_sg_lb_stats - Update sched_group's statistics for load balancing. * @env: The load balancing environment. @@ -11035,6 +11104,7 @@ static inline void update_sg_lb_stats(struct lb_env= *env, =20 sgs->group_type =3D group_classify(env->sd->imbalance_pct, group, sgs); =20 + record_sg_llc_stats(env, sgs, group); /* Computing avg_load makes sense only when group is overloaded */ if (sgs->group_type =3D=3D group_overloaded) sgs->avg_load =3D (sgs->group_load * SCHED_CAPACITY_SCALE) /