]> git.itanic.dy.fi Git - linux-stable/commitdiff
cacheinfo: Add support to check if last level cache(LLC) is valid or shared
authorSudeep Holla <sudeep.holla@arm.com>
Mon, 4 Jul 2022 10:15:49 +0000 (11:15 +0100)
committerSudeep Holla <sudeep.holla@arm.com>
Mon, 4 Jul 2022 15:22:28 +0000 (16:22 +0100)
It is useful to have helper to check if the given two CPUs share last
level cache. We can do that check by comparing fw_token or by comparing
the cache ID. Currently we check just for fw_token as the cache ID is
optional.

This helper can be used to build the llc_sibling during arch specific
topology parsing and feeding information to the sched_domains. This also
helps to get rid of llc_id in the CPU topology as it is sort of duplicate
information.

Also add helper to check if the llc information in cacheinfo is valid
or not.

Link: https://lore.kernel.org/r/20220704101605.1318280-6-sudeep.holla@arm.com
Tested-by: Ionela Voinescu <ionela.voinescu@arm.com>
Tested-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/base/cacheinfo.c
include/linux/cacheinfo.h

index 2cea9201f31c045229ce44b6a93b58f8e873434f..fdc1baa342f1c67efe3edb3a58010ef5c8047a28 100644 (file)
@@ -47,6 +47,32 @@ static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
        return sib_leaf->fw_token == this_leaf->fw_token;
 }
 
+bool last_level_cache_is_valid(unsigned int cpu)
+{
+       struct cacheinfo *llc;
+
+       if (!cache_leaves(cpu))
+               return false;
+
+       llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1);
+
+       return !!llc->fw_token;
+}
+
+bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y)
+{
+       struct cacheinfo *llc_x, *llc_y;
+
+       if (!last_level_cache_is_valid(cpu_x) ||
+           !last_level_cache_is_valid(cpu_y))
+               return false;
+
+       llc_x = per_cpu_cacheinfo_idx(cpu_x, cache_leaves(cpu_x) - 1);
+       llc_y = per_cpu_cacheinfo_idx(cpu_y, cache_leaves(cpu_y) - 1);
+
+       return cache_leaves_are_shared(llc_x, llc_y);
+}
+
 #ifdef CONFIG_OF
 /* OF properties to query for a given cache type */
 struct cache_type_info {
index 4ff37cb763ae2a243385ac0580e07574ff7546a8..7e429bc5c1a43a0200622611d6dd073d20d4b36b 100644 (file)
@@ -82,6 +82,8 @@ struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu);
 int init_cache_level(unsigned int cpu);
 int populate_cache_leaves(unsigned int cpu);
 int cache_setup_acpi(unsigned int cpu);
+bool last_level_cache_is_valid(unsigned int cpu);
+bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y);
 #ifndef CONFIG_ACPI_PPTT
 /*
  * acpi_find_last_cache_level is only called on ACPI enabled