From 7dbc307b6c72a5412e3f4e9fa2e0e926925fc5d6 Mon Sep 17 00:00:00 2001 From: Hui Su Date: Wed, 16 Sep 2026 00:59:53 +0900 Subject: [PATCH 1/3] sched/mmcid: Fix affinity-triggered switch back to per-task mode MM CID switches to per-CPU ownership when the number of users of an mm exceeds the maximum number of CIDs. When the affinity union grows, the per-CPU threshold is recalculated and the MM can switch back to per-task ownership through deferred work. mm_cid_calc_pcpu_thrs() incorrectly uses min(nr_cpus_allowed, users) to calculate that switch-back threshold. This makes pcpu_thrs no larger than users, so the users < pcpu_thrs check in mm_update_cpus_allowed() can never succeed. For example, with three users restricted to two CPUs, the MM enters per-CPU mode. On an eight-CPU system, widening the affinity union to all eight CPUs should produce a threshold of four, but the old calculation produces three and returns early. The MM therefore remains in per-CPU mode even though the widened CPU set makes per-task ownership preferable. Calculate pcpu_thrs from nr_cpus_allowed directly. The users bound in __mm_update_max_cids() still controls when per-CPU mode is entered, so this does not change the threshold calculated when switching from per-task to per-CPU ownership. Tested with an x86_64 QEMU reproducer using three users, an initial two-CPU affinity, and an eight-CPU affinity expansion. The baseline does not invoke mm_cid_work_fn() after the affinity expansion. The fixed kernel invokes the deferred work once and completes the switch back to per-task mode. Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions") Signed-off-by: Hui Su Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260915155953.2856524-1-sh_def@163.com --- kernel/sched/core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1754d9f95f2c..76c6499c1972 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -10852,11 +10852,10 @@ static void __mm_update_max_cids(struct mm_mm_cid *mc) static inline unsigned int mm_cid_calc_pcpu_thrs(struct mm_mm_cid *mc) { - unsigned int opt_cids; + unsigned int nr_cpus = mc->nr_cpus_allowed; - opt_cids = min(mc->nr_cpus_allowed, mc->users); /* Has to be at least 1 because 0 indicates PCPU mode off */ - return max(min(opt_cids - opt_cids / 4, num_possible_cpus() / 2), 1); + return max(min(nr_cpus - nr_cpus / 4, num_possible_cpus() / 2), 1); } static bool mm_update_max_cids(struct mm_struct *mm) From ee92b7ef4c1e271b3c1ea2a8b13034bdc62422a7 Mon Sep 17 00:00:00 2001 From: Tim Chen Date: Wed, 7 Oct 2026 10:25:30 -0700 Subject: [PATCH 2/3] sched/cache: Honor asym packing over cache aware scheduling on hybrid systems A regression was reported on an AMD Ryzen AI HX 370 running a cache intensive Clang full-LTO link. The little cores run at a much lower frequency (3.3 GHz vs 5.1 GHz) and have only half of the L3 cache (8 MB vs 16 MB), so pinning such a task to the little-core LLC hurts twice, and full-LTO builds slow down dramatically compared to pre-cache-aware-scheduling kernels. Asym packing and cache aware scheduling express conflicting placement strategies. Asym packing wants a task to run on the highest priority CPU, whereas cache aware scheduling wants to co-locate the tasks of a process on one LLC regardless of the priority of CPUs in that LLC. When asym packing tries to migrate task to an idle core that has higher priority than source cpu, let asym packing win. Moving tasks to a higher performing idle core will buy more performance than cache co-location. Prioritize asym packing over LLC balancing for regular and active load balancing. Fixes: 23b2b5ccc45c ("sched/cache: Introduce helper functions to enforce LLC migration policy") Closes: https://lore.kernel.org/lkml/2180ea5a-eb28-4152-8d4d-cd00b0c24b2e@computerix.info/ Reported-by: Klaus Kusche Suggested-by: Kayra Cizmeci Signed-off-by: Tim Chen Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Kayra Cizmeci Tested-by: Klaus Kusche Tested-by: Ricardo Neri Tested-by: Chen Yu Cc: stable@vger.kernel.org Cc: stable@vger.kernel.org # 7.2.x Link: https://patch.msgid.link/b29badede27bb6bfb4a759e06754cb19657f0778.1791308631.git.tim.c.chen@linux.intel.com --- kernel/sched/fair.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0f2364479f9d..d750f2f30f37 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10942,6 +10942,8 @@ static inline bool task_misfits_asym_cpu(struct lb_env *env, struct task_struct return false; } +static inline bool sched_asym(struct sched_domain *sd, int dst_cpu, int src_cpu); + /* * Check if task p can migrate from source LLC to * destination LLC in terms of cache aware load balance. @@ -10966,6 +10968,10 @@ static enum llc_mig can_migrate_llc_task(struct lb_env *env, if (cpu < 0 || cpus_share_cache(src_cpu, dst_cpu)) return mig_unrestricted; + /* Prioritize asym packing to idle core over cache awareness */ + if (env->idle && sched_asym(env->sd, dst_cpu, src_cpu)) + return mig_unrestricted; + /* skip cache aware load balance for too many threads */ if (invalid_llc_nr(grp, p, dst_cpu) || exceed_llc_capacity(grp, dst_cpu)) { @@ -12162,6 +12168,14 @@ static inline bool llc_balance(struct lb_env *env, struct sg_lb_stats *sgs, sgs->group_misfit_task_load) return false; + /* + * On asym packing domains, if the destination CPU + * has higher priority than all CPUs in the source group, + * prioritize asym packing. + */ + if (sgs->group_asym_packing) + return false; + /* * Skip cache aware tagging if nr_balanced_failed is sufficiently high. * Threshold of cache_nice_tries is set to 1 higher than nr_balance_failed @@ -13577,12 +13591,12 @@ static int need_active_balance(struct lb_env *env) { struct sched_domain *sd = env->sd; - if (alb_break_llc(env)) - return 0; - if (asym_active_balance(env)) return 1; + if (alb_break_llc(env)) + return 0; + if (imbalanced_active_balance(env)) return 1; From cac037a85c1971ec75c4d3edf5a28af9ec2a089c Mon Sep 17 00:00:00 2001 From: Yafang Shao Date: Fri, 23 Oct 2026 10:31:04 +0800 Subject: [PATCH 3/3] sched: fix stale get_pref_llc() stub for !CONFIG_SCHED_CACHE Commit b636fef85bda ("sched/cache: Introduce task_struct->sched_cache_grp to fix UAF") switched get_pref_llc() from taking a struct mm_struct * to taking the task's struct sched_cache_group *, but only updated the CONFIG_SCHED_CACHE definition and its caller: the stub in the !CONFIG_SCHED_CACHE branch kept the old mm_struct parameter. Fixes: b636fef85bda ("sched/cache: Introduce task_struct->sched_cache_grp to fix UAF") Signed-off-by: Yafang Shao Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Gregory Price (Meta) Reviewed-by: Chen Yu Reviewed-by: Tim Chen Cc: #v7.2.x Link: https://patch.msgid.link/20261023023105.28829-2-laoar.shao@gmail.com --- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index d750f2f30f37..6057bb53425e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2194,7 +2194,7 @@ void init_sched_mm(struct task_struct *p) { } static void task_tick_cache(struct rq *rq, struct task_struct *p) { } static inline int get_pref_llc(struct task_struct *p, - struct mm_struct *mm) + struct sched_cache_group *grp) { return -1; }