From nobody Sat Jul 25 06:09:21 2026 Received: from canpmsgout10.his.huawei.com (canpmsgout10.his.huawei.com [113.46.200.225]) (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 893B0318BA6 for ; Fri, 17 Jul 2026 03:49:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.225 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784260160; cv=none; b=pzwZyRkdGCm36WSxa/5fJHhft2tFMBPw0WxTvBV0G06pXx0Ai7OtsK1J0BObHueq+yBJOlbP33lU9HECySKehs4kRXoiqCjmb2y6D68xvYzxg9ZTjxHjT2xqUzBx5sggfBJveNYSdYZRW2KV5714ZYPnsC/a2/yRze1UogiKKac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784260160; c=relaxed/simple; bh=RirR5KnlFOe3QbbMCTW5s6TZqahR/KiPgV34UeHFz5M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NTv1q/atIatl2H0ySSzi67KqL7xM52NNWzXGyPAEmFZ8JbsYZ761J1JEbMqQfFRFa7ukiFReS5+T+VUwZR/tkeuAEV46LrUns67R9ekKfDAzu48cEg1dRSy+vKOw8mSAcbsdFJax+Rj2BBz1oEBiegqAbS9QYBYUkoVFaUVzOhA= 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=MVZxiNSg; arc=none smtp.client-ip=113.46.200.225 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="MVZxiNSg" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=MHF4hIHW9UVqxUsP52OilzVXrzUrhn80tyhjwNL8Tbc=; b=MVZxiNSgG7225Dk/qCjQx3dVFhAIA5ywqdQ6Ed/LRuY3hXfFcDcozdrePpuu8aQNusug7cTQh oHJ7YslpbJYd/1wixqIzqayGQKmE7YLNU5vV2ujOe0splx14SIaHU3uovvKW3Llp2yjRPWS+SYK ERvKxTomxtS5yw/OAQnmosY= Received: from mail.maildlp.com (unknown [172.19.163.15]) by canpmsgout10.his.huawei.com (SkyGuard) with ESMTPS id 4h1bJX4jp4z1K98V; Fri, 17 Jul 2026 11:39:56 +0800 (CST) Received: from kwepemj100017.china.huawei.com (unknown [7.202.194.11]) by mail.maildlp.com (Postfix) with ESMTPS id D3B984058E; Fri, 17 Jul 2026 11:49:14 +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; Fri, 17 Jul 2026 11:49:14 +0800 From: Luo Gengkun To: , , , , , CC: , , , , , , Subject: [PATCH v6 linux 1/2] sched/cache: Reduce the overhead of task_cache_work by only scan the visisted cpus Date: Fri, 17 Jul 2026 04:12:30 +0000 Message-ID: <20260717041231.3324851-2-luogengkun2@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260717041231.3324851-1-luogengkun2@huawei.com> References: <20260717041231.3324851-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: quoted-printable X-ClientProxiedBy: kwepems500001.china.huawei.com (7.221.188.70) To kwepemj100017.china.huawei.com (7.202.194.11) Content-Type: text/plain; charset="utf-8" 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/mm_types.h | 6 ++++++ include/linux/sched.h | 2 ++ kernel/sched/fair.c | 37 +++++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index b18c2b2e7d2c..35559079e4d4 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -1620,6 +1620,11 @@ static inline int mm_alloc_sched_noprof(struct mm_st= ruct *mm) if (!pcpu_sched) return -ENOMEM; =20 + if (!zalloc_cpumask_var(&mm->sc_stat.visited_cpus, GFP_KERNEL)) { + free_percpu(pcpu_sched); + return -ENOMEM; + } + mm_init_sched(mm, pcpu_sched); return 0; } @@ -1630,6 +1635,7 @@ static inline void mm_destroy_sched(struct mm_struct = *mm) { free_percpu(mm->sc_stat.pcpu_sched); mm->sc_stat.pcpu_sched =3D NULL; + free_cpumask_var(mm->sc_stat.visited_cpus); } #else /* !CONFIG_SCHED_CACHE */ =20 diff --git a/include/linux/sched.h b/include/linux/sched.h index 373bcc0598d1..b461a71a65da 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2388,6 +2388,7 @@ static __always_inline int task_mm_cid(struct task_st= ruct *t) struct sched_cache_time { u64 runtime; unsigned long epoch; + unsigned long epoch_last_visit; }; =20 struct sched_cache_stat { @@ -2398,6 +2399,7 @@ struct sched_cache_stat { unsigned long next_scan; unsigned long footprint; int cpu; + cpumask_var_t visited_cpus; } ____cacheline_aligned_in_smp; =20 #else diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index d78467ec6ee1..ab9010b2ec49 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 =3D 0; /* a slightly stale cpu epoch is acceptible */ pcpu_sched->epoch =3D rq->cpu_epoch; + pcpu_sched->epoch_last_visit =3D rq->cpu_epoch; epoch =3D rq->cpu_epoch; } =20 @@ -1635,13 +1636,23 @@ static inline void __update_mm_sched(struct rq *rq, } } =20 -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 =3D + per_cpu_ptr(mm->sc_stat.pcpu_sched, cpu); + struct rq *rq =3D cpu_rq(cpu); + guard(raw_spinlock_irqsave)(&rq->cpu_epoch_lock); =20 __update_mm_sched(rq, pcpu_sched); =20 + /* Skip the rq that has not been hit for a long time */ + if ((rq->cpu_epoch - pcpu_sched->epoch_last_visit) > llc_epoch_affinity_t= imeout) { + cpumask_clear_cpu(cpu, mm->sc_stat.visited_cpus); + return 0; + } + /* * Runtime is a geometric series (r=3D0.5) and as such will sum to twice * the accumulation period, this means the multiplcation here should @@ -1711,6 +1722,9 @@ void account_mm_sched(struct rq *rq, struct task_stru= ct *p, s64 delta_exec) pcpu_sched->runtime +=3D delta_exec; rq->cpu_runtime +=3D delta_exec; epoch =3D rq->cpu_epoch; + pcpu_sched->epoch_last_visit =3D epoch; + if (!cpumask_test_cpu(cpu_of(rq), mm->sc_stat.visited_cpus)) + cpumask_set_cpu(cpu_of(rq), mm->sc_stat.visited_cpus); } =20 /* @@ -1867,6 +1881,7 @@ static void task_cache_work(struct callback_head *wor= k) guard(rcu)(); =20 get_scan_cpumasks(cpus, p); + cpumask_and(cpus, cpus, mm->sc_stat.visited_cpus); =20 for_each_cpu(cpu, cpus) { /* XXX sched_cluster_active */ @@ -1877,19 +1892,21 @@ static void task_cache_work(struct callback_head *w= ork) if (!sd) continue; =20 - for_each_cpu(i, sched_domain_span(sd)) { - occ =3D fraction_mm_sched(cpu_rq(i), - per_cpu_ptr(mm->sc_stat.pcpu_sched, i)); + for_each_cpu_and(i, sched_domain_span(sd), mm->sc_stat.visited_cpus) { + cur =3D rcu_dereference_all(cpu_rq(i)->curr); + if (cur && !(cur->flags & (PF_EXITING | PF_KTHREAD)) && + cur->mm =3D=3D mm) + nr_running++; + + occ =3D fraction_mm_sched(i, mm); + if (occ =3D=3D 0) + continue; + a_occ +=3D occ; if (occ > m_occ) { m_occ =3D occ; m_cpu =3D i; } - - cur =3D rcu_dereference_all(cpu_rq(i)->curr); - if (cur && !(cur->flags & (PF_EXITING | PF_KTHREAD)) && - cur->mm =3D=3D mm) - nr_running++; } =20 /* --=20 2.34.1 From nobody Sat Jul 25 06:09:21 2026 Received: from canpmsgout11.his.huawei.com (canpmsgout11.his.huawei.com [113.46.200.226]) (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 BB85231D381 for ; Fri, 17 Jul 2026 03:49:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.226 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784260160; cv=none; b=YRfe2ECdMqx7jzZdG5IW57VK1TaRq6cVzNLdbRNG79JuUxiLttsQIB2daPr5kZye3DBh1J7BNigCZylGoWxPVI8gA9YIaemCv5JtWn05R3u4wFPGbtmtr2IWr+zpov1c3kPXL33TDwtCZiEeKDtC7BzsWRbam4BWZ3REVYo0ebg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784260160; c=relaxed/simple; bh=MMBZ8fYZGxF9qY5GW9PPJt74eRnBe7CI3OUMucDOpWA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=C/HEYCiBgX5rO88Ee4Xob8STwKP01wWMaPWywybkTrM/7DKamZn/wDs+YB2sivENCTSNBFjr6PMttJ5pehKCtXGZnWi9cpoe9F0gxNWKtW8UZSd9UMqQJByylLD14/pFwbW0Zf0oEFOQ+7xM70JfG8yk9UQQGlQpWKzYPR2D7ss= 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=00Ca7XAR; arc=none smtp.client-ip=113.46.200.226 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="00Ca7XAR" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=darMPwiymr60UBfYJZRCQRR5X7ZyxJ6X+aAnP75tKhQ=; b=00Ca7XARmWDl9Qu1YOlMztSB54p1fH3Q/p6joXvvS1s0Y+kqnHByLTnadwOd0iU679SEcWfLX 88n7BgYTzMD/z5QoOcZzjm/Voyg4DVKNz9O+BpbdKciq0MBQMHeZD+0uTNGhMrnGjjD9m01g4mI k9ZmIZNXwNrBaqNhZfLWQKk= Received: from mail.maildlp.com (unknown [172.19.163.200]) by canpmsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4h1bJT30D0zKmSx; Fri, 17 Jul 2026 11:39:53 +0800 (CST) Received: from kwepemj100017.china.huawei.com (unknown [7.202.194.11]) by mail.maildlp.com (Postfix) with ESMTPS id 5A87740563; Fri, 17 Jul 2026 11:49:15 +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; Fri, 17 Jul 2026 11:49:14 +0800 From: Luo Gengkun To: , , , , , CC: , , , , , , Subject: [PATCH v6 linux 2/2] -- DO NOT APPLY!!! -- sched/cache/debug: Add trace event and sched feature to track scan cost Date: Fri, 17 Jul 2026 04:12:31 +0000 Message-ID: <20260717041231.3324851-3-luogengkun2@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260717041231.3324851-1-luogengkun2@huawei.com> References: <20260717041231.3324851-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: quoted-printable X-ClientProxiedBy: kwepems500001.china.huawei.com (7.221.188.70) To kwepemj100017.china.huawei.com (7.202.194.11) Content-Type: text/plain; charset="utf-8" To evaluate the effectiveness of the previous patch, this debug patch re-ad= ds get_scan_cpumasks() and introduces two sched features as well as trace events to facilitate testing. Signed-off-by: Luo Gengkun --- include/trace/events/sched.h | 21 +++++++++++++++++++++ kernel/sched/fair.c | 26 +++++++++++++++++++++----- kernel/sched/features.h | 1 + 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 535860581f15..aced624f198d 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h @@ -10,6 +10,27 @@ #include #include =20 +TRACE_EVENT(sched_cache_scan, + + TP_PROTO(struct task_struct *t, int scan), + + TP_ARGS(t, scan), + + TP_STRUCT__entry( + __string( comm, t->comm ) + __field( pid_t, pid ) + __field( int, scan ) + ), + + TP_fast_assign( + __assign_str(comm); + __entry->pid =3D t->pid; + __entry->scan =3D scan; + ), + + TP_printk("comm=3D%s pid=3D%d scan=3D%d", __get_str(comm), __entry->pid, + __entry->scan) +); /* * Tracepoint for calling kthread_stop, performed to end a kthread: */ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ab9010b2ec49..b5b598bf86bb 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1648,7 +1648,8 @@ static unsigned long fraction_mm_sched(int cpu, __update_mm_sched(rq, pcpu_sched); =20 /* Skip the rq that has not been hit for a long time */ - if ((rq->cpu_epoch - pcpu_sched->epoch_last_visit) > llc_epoch_affinity_t= imeout) { + if (sched_feat(SC_VISIT) && + (rq->cpu_epoch - pcpu_sched->epoch_last_visit) > llc_epoch_affinity_t= imeout) { cpumask_clear_cpu(cpu, mm->sc_stat.visited_cpus); return 0; } @@ -1723,7 +1724,8 @@ void account_mm_sched(struct rq *rq, struct task_stru= ct *p, s64 delta_exec) rq->cpu_runtime +=3D delta_exec; epoch =3D rq->cpu_epoch; pcpu_sched->epoch_last_visit =3D epoch; - if (!cpumask_test_cpu(cpu_of(rq), mm->sc_stat.visited_cpus)) + if (sched_feat(SC_VISIT) && + !cpumask_test_cpu(cpu_of(rq), mm->sc_stat.visited_cpus)) cpumask_set_cpu(cpu_of(rq), mm->sc_stat.visited_cpus); } =20 @@ -1846,7 +1848,8 @@ static void task_cache_work(struct callback_head *wor= k) unsigned long curr_m_a_occ =3D 0; struct mm_struct *mm =3D p->mm; unsigned long m_a_occ =3D 0; - cpumask_var_t cpus; + cpumask_var_t cpus, scan_cpus; + int scanned =3D 0; =20 WARN_ON_ONCE(work !=3D &p->cache_work); =20 @@ -1877,11 +1880,17 @@ static void task_cache_work(struct callback_head *w= ork) if (!zalloc_cpumask_var(&cpus, GFP_KERNEL)) return; =20 + if (!zalloc_cpumask_var(&scan_cpus, GFP_KERNEL)) { + free_cpumask_var(cpus); + return; + } + scoped_guard (cpus_read_lock) { guard(rcu)(); =20 get_scan_cpumasks(cpus, p); - cpumask_and(cpus, cpus, mm->sc_stat.visited_cpus); + if (sched_feat(SC_VISIT)) + cpumask_and(cpus, cpus, mm->sc_stat.visited_cpus); =20 for_each_cpu(cpu, cpus) { /* XXX sched_cluster_active */ @@ -1892,12 +1901,17 @@ static void task_cache_work(struct callback_head *w= ork) if (!sd) continue; =20 - for_each_cpu_and(i, sched_domain_span(sd), mm->sc_stat.visited_cpus) { + cpumask_copy(scan_cpus, sched_domain_span(sd)); + if (sched_feat(SC_VISIT)) + cpumask_and(scan_cpus, scan_cpus, mm->sc_stat.visited_cpus); + + for_each_cpu(i, scan_cpus) { cur =3D rcu_dereference_all(cpu_rq(i)->curr); if (cur && !(cur->flags & (PF_EXITING | PF_KTHREAD)) && cur->mm =3D=3D mm) nr_running++; =20 + scanned++; occ =3D fraction_mm_sched(i, mm); if (occ =3D=3D 0) continue; @@ -1952,6 +1966,8 @@ static void task_cache_work(struct callback_head *wor= k) =20 update_avg_scale(&mm->sc_stat.nr_running_avg, nr_running); free_cpumask_var(cpus); + free_cpumask_var(scan_cpus); + trace_sched_cache_scan(p, scanned); } =20 void init_sched_mm(struct task_struct *p) diff --git a/kernel/sched/features.h b/kernel/sched/features.h index 8f0dee8fc475..990714ebabfd 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -142,3 +142,4 @@ SCHED_FEAT(LATENCY_WARN, false) */ SCHED_FEAT(NI_RANDOM, true) SCHED_FEAT(NI_RATE, true) +SCHED_FEAT(SC_VISIT, false) --=20 2.34.1