]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sparc64: Setup a scheduling domain for highest level cache.
authorAtish Patra <atish.patra@oracle.com>
Thu, 20 Oct 2016 00:33:29 +0000 (18:33 -0600)
committerAllen Pais <allen.pais@oracle.com>
Sun, 22 Jan 2017 15:36:51 +0000 (21:06 +0530)
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 <atish.patra@oracle.com>
Reviewed-by: Chris Hyser <chris.hyser@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 1e655ca52bb2727471f20cf4d8f62b4b9f69e6fc)
Signed-off-by: Allen Pais <allen.pais@oracle.com>
arch/sparc/include/asm/topology_64.h
arch/sparc/kernel/mdesc.c
arch/sparc/kernel/smp_64.c

index 637ced3c1c2e10df180d25410f8926e4f8a7b9ed..01624fa6282e3b3b6608a450b6e70a81f72cce21 100644 (file)
@@ -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 */
index af177d81d3d7b5b68bf49c714d92b4431a9927e3..db3e4335d6667d7abe076496200c0c3509ffdaae 100644 (file)
@@ -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);
index 6263c03ab2a5f929f1a54b98d0eac9031845c240..c7e13dcf49e767a210bd954d31c21e7f65303ca1 100644 (file)
@@ -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]);
                }
        }