From: Atish Patra Date: Thu, 20 Oct 2016 00:33:29 +0000 (-0600) Subject: sparc64: Setup a scheduling domain for highest level cache. X-Git-Tag: v4.1.12-92~12^2~16 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7d50bc81b5a5171d85fa3125f0198b59b1c3a869;p=users%2Fjedix%2Flinux-maple.git sparc64: Setup a scheduling domain for highest level cache. Individual scheduler domain should consist different hierarchy consisting of cores sharing similar property. Currently, no scheduler domain is defined separately for the cores that shares the last level cache. As a result, the scheduler fails to take advantage of cache locality while migrating tasks during load balancing. Here are the cpu masks currently present for sparc that are/can be used in scheduler domain construction. cpu_core_map : set based on the cores that shares l1 cache. core_core_sib_map : is set based on the socket id or max cache id. The prior SPARC notion of socket was defined as highest level of shared cache. However, the MD record on T7 platforms now describes the CPUs that share the physical socket and this is no longer tied to shared cache. That's why a separate cpu mask needs to be created that truly represent highest level of shared cache for all platforms. Modified after cherry picked from upstream commit. d624716b6c67e60681180786564b92ddb521148a The implementation is largely based on Chris's patches. Signed-off-by: Atish Patra Reviewed-by: Chris Hyser Signed-off-by: David S. Miller (cherry picked from commit 1e655ca52bb2727471f20cf4d8f62b4b9f69e6fc) Signed-off-by: Allen Pais --- diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index 637ced3c1c2e1..01624fa6282e3 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h @@ -45,13 +45,19 @@ int __node_distance(int, int); #define topology_core_id(cpu) (cpu_data(cpu).core_id) #define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu]) #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) +#define topology_core_cache_cpumask(cpu) (&cpu_core_sib_cache_map[cpu]) #endif /* CONFIG_SMP */ extern cpumask_t cpu_core_map[NR_CPUS]; extern cpumask_t cpu_core_sib_map[NR_CPUS]; +extern cpumask_t cpu_core_sib_cache_map[NR_CPUS]; + +/** + * Return cores that shares the last level cache. + */ static inline const struct cpumask *cpu_coregroup_mask(int cpu) { - return &cpu_core_map[cpu]; + return &cpu_core_sib_cache_map[cpu]; } #endif /* _ASM_SPARC64_TOPOLOGY_H */ diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index af177d81d3d7b..db3e4335d6667 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -863,14 +863,15 @@ static void __mark_core_id(struct mdesc_handle *hp, u64 node, } static void __mark_max_cache_id(struct mdesc_handle *hp, u64 node, - int max_cache_id) + int max_cache_id) { const u64 *id = mdesc_get_property(hp, node, "id", NULL); if (*id < num_possible_cpus()) { cpu_data(*id).max_cache_id = max_cache_id; - /* On systems without explict socket descriptions socket + /** + * On systems without explicit socket descriptions socket * is max_cache_id */ cpu_data(*id).sock_id = max_cache_id; @@ -884,7 +885,7 @@ static void mark_core_ids(struct mdesc_handle *hp, u64 mp, } static void mark_max_cache_ids(struct mdesc_handle *hp, u64 mp, - int max_cache_id) + int max_cache_id) { find_back_node_value(hp, mp, "cpu", __mark_max_cache_id, max_cache_id, 10); @@ -918,14 +919,14 @@ static void set_core_ids(struct mdesc_handle *hp) } } -static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, - int level) +static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, int level) { u64 mp; int idx = 1; int fnd = 0; - /* Identify unique highest level of shared cache by looking for cpus + /** + * Identify unique highest level of shared cache by looking for cpus * backpointed to by shared level N caches. */ mdesc_for_each_node_by_name(hp, mp, "cache") { @@ -934,7 +935,6 @@ static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, cur_lvl = mdesc_get_property(hp, mp, "level", NULL); if (*cur_lvl != level) continue; - mark_max_cache_ids(hp, mp, idx); idx++; fnd = 1; @@ -970,14 +970,14 @@ static void set_sock_ids(struct mdesc_handle *hp) { u64 mp; - /* Find the highest level of shared cache which pre-T7 is also + /** + * Find the highest level of shared cache which pre-T7 is also * the socket. */ if (!set_max_cache_ids_by_cache(hp, 3)) set_max_cache_ids_by_cache(hp, 2); - /* If machine description exposes sockets data use it. - */ + /* If machine description exposes sockets data use it.*/ mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets"); if (mp != MDESC_NODE_NULL) set_sock_ids_by_socket(hp, mp); diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 6263c03ab2a5f..c7e13dcf49e76 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -65,9 +65,13 @@ cpumask_t cpu_core_map[NR_CPUS] __read_mostly = cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; +cpumask_t cpu_core_sib_cache_map[NR_CPUS] __read_mostly = { + [0 ... NR_CPUS - 1] = CPU_MASK_NONE }; + EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); EXPORT_SYMBOL(cpu_core_map); EXPORT_SYMBOL(cpu_core_sib_map); +EXPORT_SYMBOL(cpu_core_sib_cache_map); static cpumask_t smp_commenced_mask; @@ -1279,6 +1283,9 @@ void smp_fill_in_sib_core_maps(void) for_each_present_cpu(j) { if (cpu_data(i).max_cache_id == cpu_data(j).max_cache_id) + cpumask_set_cpu(j, &cpu_core_sib_cache_map[i]); + + if (cpu_data(i).sock_id == cpu_data(j).sock_id) cpumask_set_cpu(j, &cpu_core_sib_map[i]); } }