openeuler inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I77UDW CVE: NA
--------------------------------
The MPAM table identifies caches by id, but the driver also wants to know the processor node.
Add a helper that walks every possible cache, until it finds the one identified by id, then return processor node.
Signed-off-by: Yu Liao liaoyu15@huawei.com --- drivers/acpi/pptt.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 5 ++++ 2 files changed, 60 insertions(+)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index 879b9155b7b4..74ce9fcee830 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -896,3 +896,58 @@ int find_acpi_cpu_topology_hetero_id(unsigned int cpu) return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, ACPI_PPTT_ACPI_IDENTICAL); } + +struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id) +{ + u32 acpi_cpu_id; + acpi_status status; + int level, cpu, num_levels; + struct acpi_pptt_cache *cache; + struct acpi_table_header *table; + struct acpi_pptt_cache_v1 *cache_v1; + struct acpi_pptt_processor *cpu_node; + + status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); + if (ACPI_FAILURE(status)) { + pr_warn_once("No PPTT table found, cache topology may be inaccurate\n"); + return NULL; + } + + if (table->revision < 3) { + acpi_put_table(table); + return NULL; + } + + /* + * If we found the cache first, we'd still need to walk from each CPU + * to find the level... + */ + for_each_possible_cpu(cpu) { + acpi_cpu_id = get_acpi_id_for_cpu(cpu); + cpu_node = acpi_find_processor_node(table, acpi_cpu_id); + if (!cpu_node) + break; + num_levels = acpi_count_levels(table, cpu_node); + + for (level = 0; level <= num_levels; level++) { + cache = acpi_find_cache_node(table, acpi_cpu_id, + ACPI_PPTT_CACHE_TYPE_UNIFIED, + level, &cpu_node); + if (!cache) + continue; + + cache_v1 = ACPI_ADD_PTR(struct acpi_pptt_cache_v1, + cache, + sizeof(struct acpi_pptt_cache)); + + if (cache->flags & ACPI_PPTT_CACHE_ID_VALID && + cache_v1->cache_id == cache_id) { + acpi_put_table(table); + return cpu_node; + } + } + } + + acpi_put_table(table); + return NULL; +} diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 4a0142276cb8..3669c2ff26ed 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1331,6 +1331,7 @@ int find_acpi_cpu_topology(unsigned int cpu, int level); int find_acpi_cpu_topology_package(unsigned int cpu); int find_acpi_cpu_topology_hetero_id(unsigned int cpu); int find_acpi_cpu_cache_topology(unsigned int cpu, int level); +struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id); #else static inline int acpi_pptt_cpu_is_thread(unsigned int cpu) { @@ -1352,6 +1353,10 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level) { return -EINVAL; } +static inline struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id) +{ + return NULL; +} #endif
struct acpi_pptt_processor *