Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sched: Add cpus_share_resources API

Add cpus_share_resources() API. This is the preparation for the
optimization of select_idle_cpu() on platforms with cluster scheduler
level.

On a machine with clusters cpus_share_resources() will test whether
two cpus are within the same cluster. On a non-cluster machine it
will behaves the same as cpus_share_cache(). So we use "resources"
here for cache resources.

Signed-off-by: Barry Song <song.bao.hua@hisilicon.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
Reviewed-by: Tim Chen <tim.c.chen@linux.intel.com>
Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
Tested-and-reviewed-by: Chen Yu <yu.c.chen@intel.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lkml.kernel.org/r/20231019033323.54147-2-yangyicong@huawei.com

authored by

Barry Song and committed by
Peter Zijlstra
b95303e0 5ebde09d

+40 -1
+7
include/linux/sched/sd_flags.h
··· 110 110 SD_FLAG(SD_SHARE_CPUCAPACITY, SDF_SHARED_CHILD | SDF_NEEDS_GROUPS) 111 111 112 112 /* 113 + * Domain members share CPU cluster (LLC tags or L2 cache) 114 + * 115 + * NEEDS_GROUPS: Clusters are shared between groups. 116 + */ 117 + SD_FLAG(SD_CLUSTER, SDF_NEEDS_GROUPS) 118 + 119 + /* 113 120 * Domain members share CPU package resources (i.e. caches) 114 121 * 115 122 * SHARED_CHILD: Set from the base domain up until spanned CPUs no longer share
+7 -1
include/linux/sched/topology.h
··· 45 45 #ifdef CONFIG_SCHED_CLUSTER 46 46 static inline int cpu_cluster_flags(void) 47 47 { 48 - return SD_SHARE_PKG_RESOURCES; 48 + return SD_CLUSTER | SD_SHARE_PKG_RESOURCES; 49 49 } 50 50 #endif 51 51 ··· 179 179 void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms); 180 180 181 181 bool cpus_share_cache(int this_cpu, int that_cpu); 182 + bool cpus_share_resources(int this_cpu, int that_cpu); 182 183 183 184 typedef const struct cpumask *(*sched_domain_mask_f)(int cpu); 184 185 typedef int (*sched_domain_flags_f)(void); ··· 229 228 } 230 229 231 230 static inline bool cpus_share_cache(int this_cpu, int that_cpu) 231 + { 232 + return true; 233 + } 234 + 235 + static inline bool cpus_share_resources(int this_cpu, int that_cpu) 232 236 { 233 237 return true; 234 238 }
+12
kernel/sched/core.c
··· 3939 3939 return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu); 3940 3940 } 3941 3941 3942 + /* 3943 + * Whether CPUs are share cache resources, which means LLC on non-cluster 3944 + * machines and LLC tag or L2 on machines with clusters. 3945 + */ 3946 + bool cpus_share_resources(int this_cpu, int that_cpu) 3947 + { 3948 + if (this_cpu == that_cpu) 3949 + return true; 3950 + 3951 + return per_cpu(sd_share_id, this_cpu) == per_cpu(sd_share_id, that_cpu); 3952 + } 3953 + 3942 3954 static inline bool ttwu_queue_cond(struct task_struct *p, int cpu) 3943 3955 { 3944 3956 /*
+1
kernel/sched/sched.h
··· 1853 1853 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_llc); 1854 1854 DECLARE_PER_CPU(int, sd_llc_size); 1855 1855 DECLARE_PER_CPU(int, sd_llc_id); 1856 + DECLARE_PER_CPU(int, sd_share_id); 1856 1857 DECLARE_PER_CPU(struct sched_domain_shared __rcu *, sd_llc_shared); 1857 1858 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_numa); 1858 1859 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_packing);
+13
kernel/sched/topology.c
··· 668 668 DEFINE_PER_CPU(struct sched_domain __rcu *, sd_llc); 669 669 DEFINE_PER_CPU(int, sd_llc_size); 670 670 DEFINE_PER_CPU(int, sd_llc_id); 671 + DEFINE_PER_CPU(int, sd_share_id); 671 672 DEFINE_PER_CPU(struct sched_domain_shared __rcu *, sd_llc_shared); 672 673 DEFINE_PER_CPU(struct sched_domain __rcu *, sd_numa); 673 674 DEFINE_PER_CPU(struct sched_domain __rcu *, sd_asym_packing); ··· 693 692 per_cpu(sd_llc_size, cpu) = size; 694 693 per_cpu(sd_llc_id, cpu) = id; 695 694 rcu_assign_pointer(per_cpu(sd_llc_shared, cpu), sds); 695 + 696 + sd = lowest_flag_domain(cpu, SD_CLUSTER); 697 + if (sd) 698 + id = cpumask_first(sched_domain_span(sd)); 699 + 700 + /* 701 + * This assignment should be placed after the sd_llc_id as 702 + * we want this id equals to cluster id on cluster machines 703 + * but equals to LLC id on non-Cluster machines. 704 + */ 705 + per_cpu(sd_share_id, cpu) = id; 696 706 697 707 sd = lowest_flag_domain(cpu, SD_NUMA); 698 708 rcu_assign_pointer(per_cpu(sd_numa, cpu), sd); ··· 1562 1550 */ 1563 1551 #define TOPOLOGY_SD_FLAGS \ 1564 1552 (SD_SHARE_CPUCAPACITY | \ 1553 + SD_CLUSTER | \ 1565 1554 SD_SHARE_PKG_RESOURCES | \ 1566 1555 SD_NUMA | \ 1567 1556 SD_ASYM_PACKING)