]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
powerpc/cacheinfo: Report the correct shared_cpu_map on big-cores
authorGautham R. Shenoy <ego@linux.vnet.ibm.com>
Thu, 11 Oct 2018 05:33:03 +0000 (11:03 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 13 Oct 2018 11:21:25 +0000 (22:21 +1100)
Currently on POWER9 SMT8 cores systems, in sysfs, we report the
shared_cache_map for L1 caches (both data and instruction) to be the
cpu-ids of the threads in SMT8 cores. This is incorrect since on
POWER9 SMT8 cores there are two groups of threads, each of which
shares its own L1 cache.

This patch addresses this by reporting the shared_cpu_map correctly in
sysfs for L1 caches.

Before the patch
   /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_map : 000000ff
   /sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_map : 000000ff
   /sys/devices/system/cpu/cpu1/cache/index0/shared_cpu_map : 000000ff
   /sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_map : 000000ff

After the patch
   /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_map : 00000055
   /sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_map : 00000055
   /sys/devices/system/cpu/cpu1/cache/index0/shared_cpu_map : 000000aa
   /sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_map : 000000aa

Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/cacheinfo.c

index a8f20e5928e132588a4387b6260ef1884a7a920e..be57bd07596d9cfd1ac2153c4be8650591e9067a 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/percpu.h>
 #include <linux/slab.h>
 #include <asm/prom.h>
+#include <asm/cputhreads.h>
+#include <asm/smp.h>
 
 #include "cacheinfo.h"
 
@@ -627,17 +629,48 @@ static ssize_t level_show(struct kobject *k, struct kobj_attribute *attr, char *
 static struct kobj_attribute cache_level_attr =
        __ATTR(level, 0444, level_show, NULL);
 
+static unsigned int index_dir_to_cpu(struct cache_index_dir *index)
+{
+       struct kobject *index_dir_kobj = &index->kobj;
+       struct kobject *cache_dir_kobj = index_dir_kobj->parent;
+       struct kobject *cpu_dev_kobj = cache_dir_kobj->parent;
+       struct device *dev = kobj_to_dev(cpu_dev_kobj);
+
+       return dev->id;
+}
+
+/*
+ * On big-core systems, each core has two groups of CPUs each of which
+ * has its own L1-cache. The thread-siblings which share l1-cache with
+ * @cpu can be obtained via cpu_smallcore_mask().
+ */
+static const struct cpumask *get_big_core_shared_cpu_map(int cpu, struct cache *cache)
+{
+       if (cache->level == 1)
+               return cpu_smallcore_mask(cpu);
+
+       return &cache->shared_cpu_map;
+}
+
 static ssize_t shared_cpu_map_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
 {
        struct cache_index_dir *index;
        struct cache *cache;
-       int ret;
+       const struct cpumask *mask;
+       int ret, cpu;
 
        index = kobj_to_cache_index_dir(k);
        cache = index->cache;
 
+       if (has_big_cores) {
+               cpu = index_dir_to_cpu(index);
+               mask = get_big_core_shared_cpu_map(cpu, cache);
+       } else {
+               mask  = &cache->shared_cpu_map;
+       }
+
        ret = scnprintf(buf, PAGE_SIZE - 1, "%*pb\n",
-                       cpumask_pr_args(&cache->shared_cpu_map));
+                       cpumask_pr_args(mask));
        buf[ret++] = '\n';
        buf[ret] = '\0';
        return ret;