From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from canpmsgout01.his.huawei.com (canpmsgout01.his.huawei.com [113.46.200.216]) (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 B49FF425CEA for ; Thu, 9 Jul 2026 12:38:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.216 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783600687; cv=none; b=p8PECK0Zk5azy6X+RuwwMXICaXhh4oIDlguxVnFG4i1DUcVTpMMCR1pfw5hNqZdICn0DVYZFpSOehutc+kH6/CAaHXM9pVdV/xc3EVAxx3HMkmNlxiCfmjGyKkPrHGvo6vYsN/rezryDmccctgU+YnKwsr9h9tb/e5hF4voiM3A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783600687; c=relaxed/simple; bh=CFyQwOvznkUenuhKtLTjLH/dpVCNFKD1fL88V3Bzxus=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HLsqGGEIMgy2WXTgxqzeNDT1QvX3WUlRuJIaBbo23yYvNjufv2xy+b/lPZVZofLDnXi4hJRd1kmIJeVm4agmTz8nSt/EvFxYWwH/BNOA7aubxDB6pGxRtUxLGUCbCtzpxbN49gKmz/nBYd53NFPMbm9D9zjdq6NvAF3iaQz+i/s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=ZGE9SfCW; arc=none smtp.client-ip=113.46.200.216 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="ZGE9SfCW" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=Bia2AoGLUnTUJOScDSBQkoDCO6bQVVv40MFxMxN2Kb4=; b=ZGE9SfCWqwzI3PxJsbardHt/V3coRyHss2HcLWIsLNPvW0Y+//uEg1zAo/Z6N0sUoAfo20Nes N8WtIOwkVAmGQqLyeOkmDHu5Y+8/IQe+E58uv5xF9be99x0RwxsE/287zbdwucBei8rJBJDcTVP O4FDZ6bTKjwRBhECxAO1ZcY= Received: from mail.maildlp.com (unknown [172.19.163.0]) by canpmsgout01.his.huawei.com (SkyGuard) with ESMTPS id 4gwvQf0G87z1T4gk; Thu, 9 Jul 2026 20:28:58 +0800 (CST) Received: from kwepemj100017.china.huawei.com (unknown [7.202.194.11]) by mail.maildlp.com (Postfix) with ESMTPS id 55D3F40561; Thu, 9 Jul 2026 20:38:00 +0800 (CST) Received: from huawei.com (10.67.174.193) by kwepemj100017.china.huawei.com (7.202.194.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Thu, 9 Jul 2026 20:37:59 +0800 From: Luo Gengkun To: , , , , , CC: , , , , , , Subject: [PATCH v5 1/2] sched/cache: Reduce the overhead of task_cache_work by only scan the visisted cpus Date: Thu, 9 Jul 2026 13:00:52 +0000 Message-ID: <20260709130053.2749834-2-luogengkun2@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260709130053.2749834-1-luogengkun2@huawei.com> References: <20260709130053.2749834-1-luogengkun2@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To kwepemj100017.china.huawei.com (7.202.194.11) The overhead of task_cache_work() is high, especially in multi-NUMA systems. Currently, task_cache_work() tries to find the pref_llc by scanning all CPUs in the system. However, most of these scans are meaningless, such as those for CPUs that have never been visited or were accessed a long time ago. To address this problem, introduce visited_cpus to track the visited CPUs and evict them once they have not been accessed for a duration exceeding llc_epoch_affinity_timeout. Signed-off-by: Luo Gengkun --- include/linux/sched.h | 2 ++ kernel/sched/fair.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 373bcc0598d1..b187ec927146 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2388,6 +2388,7 @@ static __always_inline int task_mm_cid(struct task_struct *t) struct sched_cache_time { u64 runtime; unsigned long epoch; + unsigned long epoch_timeout; }; struct sched_cache_stat { @@ -2398,6 +2399,7 @@ struct sched_cache_stat { unsigned long next_scan; unsigned long footprint; int cpu; + struct cpumask visited_cpus; } ____cacheline_aligned_in_smp; #else diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index d78467ec6ee1..44552168fcc3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1585,6 +1585,7 @@ void mm_init_sched(struct mm_struct *mm, pcpu_sched->runtime = 0; /* a slightly stale cpu epoch is acceptible */ pcpu_sched->epoch = rq->cpu_epoch; + pcpu_sched->epoch_timeout = rq->cpu_epoch; epoch = rq->cpu_epoch; } @@ -1594,6 +1595,7 @@ void mm_init_sched(struct mm_struct *mm, mm->sc_stat.next_scan = jiffies; mm->sc_stat.nr_running_avg = 0; mm->sc_stat.footprint = 0; + cpumask_clear(&mm->sc_stat.visited_cpus); /* * The update to mm->sc_stat should not be reordered * before initialization to mm's other fields, in case @@ -1635,11 +1637,21 @@ static inline void __update_mm_sched(struct rq *rq, } } -static unsigned long fraction_mm_sched(struct rq *rq, - struct sched_cache_time *pcpu_sched) +static unsigned long fraction_mm_sched(int cpu, + struct mm_struct *mm) { + struct sched_cache_time *pcpu_sched = + per_cpu_ptr(mm->sc_stat.pcpu_sched, cpu); + struct rq *rq = cpu_rq(cpu); + guard(raw_spinlock_irqsave)(&rq->cpu_epoch_lock); + /* Skip the rq that has not been hit for a long time */ + if ((rq->cpu_epoch - pcpu_sched->epoch_timeout) > llc_epoch_affinity_timeout) { + cpumask_clear_cpu(cpu, &mm->sc_stat.visited_cpus); + return 0; + } + __update_mm_sched(rq, pcpu_sched); /* @@ -1711,6 +1723,9 @@ void account_mm_sched(struct rq *rq, struct task_struct *p, s64 delta_exec) pcpu_sched->runtime += delta_exec; rq->cpu_runtime += delta_exec; epoch = rq->cpu_epoch; + pcpu_sched->epoch_timeout = epoch; + if (!cpumask_test_cpu(cpu_of(rq), &mm->sc_stat.visited_cpus)) + cpumask_set_cpu(cpu_of(rq), &mm->sc_stat.visited_cpus); } /* @@ -1867,6 +1882,7 @@ static void task_cache_work(struct callback_head *work) guard(rcu)(); get_scan_cpumasks(cpus, p); + cpumask_and(cpus, cpus, &mm->sc_stat.visited_cpus); for_each_cpu(cpu, cpus) { /* XXX sched_cluster_active */ @@ -1877,19 +1893,22 @@ static void task_cache_work(struct callback_head *work) if (!sd) continue; - for_each_cpu(i, sched_domain_span(sd)) { - occ = fraction_mm_sched(cpu_rq(i), - per_cpu_ptr(mm->sc_stat.pcpu_sched, i)); + for_each_cpu_and(i, sched_domain_span(sd), cpus) { + cur = rcu_dereference_all(cpu_rq(i)->curr); + if (cur && !(cur->flags & (PF_EXITING | PF_KTHREAD)) && + cur->mm == mm) + nr_running++; + + occ = fraction_mm_sched(i, mm); + if (occ == 0) + continue; + a_occ += occ; if (occ > m_occ) { m_occ = occ; m_cpu = i; } - cur = rcu_dereference_all(cpu_rq(i)->curr); - if (cur && !(cur->flags & (PF_EXITING | PF_KTHREAD)) && - cur->mm == mm) - nr_running++; } /* -- 2.34.1