Skip to content

Commit bd50036

Browse files
pierregondoissudeep-holla
authored andcommitted
ACPI: PPTT: Update acpi_find_last_cache_level() to acpi_get_cache_info()
acpi_find_last_cache_level() allows to find the last level of cache for a given CPU. The function is only called on arm64 ACPI based platforms to check for cache information that would be missing in the CLIDR_EL1 register. To allow populating (struct cpu_cacheinfo).num_leaves by only parsing a PPTT, update acpi_find_last_cache_level() to get the 'split_levels', i.e. the number of cache levels being split in data/instruction caches. It is assumed that there will not be data/instruction caches above a unified cache. If a split level consist of one data cache and no instruction cache (or opposite), then the missing cache will still be populated by default with minimal cache information, and maximal cpumask (all non-existing caches have the same fw_token). Suggested-by: Jeremy Linton <[email protected]> Signed-off-by: Pierre Gondois <[email protected]> Reviewed-by: Jeremy Linton <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Acked-by: Palmer Dabbelt <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sudeep Holla <[email protected]>
1 parent fa4d566 commit bd50036

File tree

3 files changed

+63
-33
lines changed

3 files changed

+63
-33
lines changed

arch/arm64/kernel/cacheinfo.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,
4646
int init_cache_level(unsigned int cpu)
4747
{
4848
unsigned int ctype, level, leaves;
49-
int fw_level;
49+
int fw_level, ret;
5050
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
5151

5252
for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) {
@@ -59,10 +59,13 @@ int init_cache_level(unsigned int cpu)
5959
leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1;
6060
}
6161

62-
if (acpi_disabled)
62+
if (acpi_disabled) {
6363
fw_level = of_find_last_cache_level(cpu);
64-
else
65-
fw_level = acpi_find_last_cache_level(cpu);
64+
} else {
65+
ret = acpi_get_cache_info(cpu, &fw_level, NULL);
66+
if (ret < 0)
67+
return ret;
68+
}
6669

6770
if (fw_level < 0)
6871
return fw_level;

drivers/acpi/pptt.c

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static inline bool acpi_pptt_match_type(int table_type, int type)
8181
* acpi_pptt_walk_cache() - Attempt to find the requested acpi_pptt_cache
8282
* @table_hdr: Pointer to the head of the PPTT table
8383
* @local_level: passed res reflects this cache level
84+
* @split_levels: Number of split cache levels (data/instruction).
8485
* @res: cache resource in the PPTT we want to walk
8586
* @found: returns a pointer to the requested level if found
8687
* @level: the requested cache level
@@ -100,6 +101,7 @@ static inline bool acpi_pptt_match_type(int table_type, int type)
100101
*/
101102
static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
102103
unsigned int local_level,
104+
unsigned int *split_levels,
103105
struct acpi_subtable_header *res,
104106
struct acpi_pptt_cache **found,
105107
unsigned int level, int type)
@@ -113,8 +115,17 @@ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
113115
while (cache) {
114116
local_level++;
115117

118+
if (!(cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)) {
119+
cache = fetch_pptt_cache(table_hdr, cache->next_level_of_cache);
120+
continue;
121+
}
122+
123+
if (split_levels &&
124+
(acpi_pptt_match_type(cache->attributes, ACPI_PPTT_CACHE_TYPE_DATA) ||
125+
acpi_pptt_match_type(cache->attributes, ACPI_PPTT_CACHE_TYPE_INSTR)))
126+
*split_levels = local_level;
127+
116128
if (local_level == level &&
117-
cache->flags & ACPI_PPTT_CACHE_TYPE_VALID &&
118129
acpi_pptt_match_type(cache->attributes, type)) {
119130
if (*found != NULL && cache != *found)
120131
pr_warn("Found duplicate cache level/type unable to determine uniqueness\n");
@@ -135,8 +146,8 @@ static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
135146
static struct acpi_pptt_cache *
136147
acpi_find_cache_level(struct acpi_table_header *table_hdr,
137148
struct acpi_pptt_processor *cpu_node,
138-
unsigned int *starting_level, unsigned int level,
139-
int type)
149+
unsigned int *starting_level, unsigned int *split_levels,
150+
unsigned int level, int type)
140151
{
141152
struct acpi_subtable_header *res;
142153
unsigned int number_of_levels = *starting_level;
@@ -149,7 +160,8 @@ acpi_find_cache_level(struct acpi_table_header *table_hdr,
149160
resource++;
150161

151162
local_level = acpi_pptt_walk_cache(table_hdr, *starting_level,
152-
res, &ret, level, type);
163+
split_levels, res, &ret,
164+
level, type);
153165
/*
154166
* we are looking for the max depth. Since its potentially
155167
* possible for a given node to have resources with differing
@@ -165,29 +177,29 @@ acpi_find_cache_level(struct acpi_table_header *table_hdr,
165177
}
166178

167179
/**
168-
* acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches
180+
* acpi_count_levels() - Given a PPTT table, and a CPU node, count the cache
181+
* levels and split cache levels (data/instruction).
169182
* @table_hdr: Pointer to the head of the PPTT table
170183
* @cpu_node: processor node we wish to count caches for
184+
* @levels: Number of levels if success.
185+
* @split_levels: Number of split cache levels (data/instruction) if
186+
* success. Can by NULL.
171187
*
172188
* Given a processor node containing a processing unit, walk into it and count
173189
* how many levels exist solely for it, and then walk up each level until we hit
174190
* the root node (ignore the package level because it may be possible to have
175-
* caches that exist across packages). Count the number of cache levels that
176-
* exist at each level on the way up.
177-
*
178-
* Return: Total number of levels found.
191+
* caches that exist across packages). Count the number of cache levels and
192+
* split cache levels (data/instruction) that exist at each level on the way
193+
* up.
179194
*/
180-
static int acpi_count_levels(struct acpi_table_header *table_hdr,
181-
struct acpi_pptt_processor *cpu_node)
195+
static void acpi_count_levels(struct acpi_table_header *table_hdr,
196+
struct acpi_pptt_processor *cpu_node,
197+
unsigned int *levels, unsigned int *split_levels)
182198
{
183-
int total_levels = 0;
184-
185199
do {
186-
acpi_find_cache_level(table_hdr, cpu_node, &total_levels, 0, 0);
200+
acpi_find_cache_level(table_hdr, cpu_node, levels, split_levels, 0, 0);
187201
cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
188202
} while (cpu_node);
189-
190-
return total_levels;
191203
}
192204

193205
/**
@@ -321,7 +333,7 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta
321333

322334
while (cpu_node && !found) {
323335
found = acpi_find_cache_level(table_hdr, cpu_node,
324-
&total_levels, level, acpi_type);
336+
&total_levels, NULL, level, acpi_type);
325337
*node = cpu_node;
326338
cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
327339
}
@@ -589,36 +601,48 @@ static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
589601
}
590602

591603
/**
592-
* acpi_find_last_cache_level() - Determines the number of cache levels for a PE
604+
* acpi_get_cache_info() - Determine the number of cache levels and
605+
* split cache levels (data/instruction) and for a PE.
593606
* @cpu: Kernel logical CPU number
607+
* @levels: Number of levels if success.
608+
* @split_levels: Number of levels being split (i.e. data/instruction)
609+
* if success. Can by NULL.
594610
*
595611
* Given a logical CPU number, returns the number of levels of cache represented
596612
* in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
597613
* indicating we didn't find any cache levels.
598614
*
599-
* Return: Cache levels visible to this core.
615+
* Return: -ENOENT if no PPTT table or no PPTT processor struct found.
616+
* 0 on success.
600617
*/
601-
int acpi_find_last_cache_level(unsigned int cpu)
618+
int acpi_get_cache_info(unsigned int cpu, unsigned int *levels,
619+
unsigned int *split_levels)
602620
{
603621
struct acpi_pptt_processor *cpu_node;
604622
struct acpi_table_header *table;
605-
int number_of_levels = 0;
606623
u32 acpi_cpu_id;
607624

625+
*levels = 0;
626+
if (split_levels)
627+
*split_levels = 0;
628+
608629
table = acpi_get_pptt();
609630
if (!table)
610631
return -ENOENT;
611632

612-
pr_debug("Cache Setup find last level CPU=%d\n", cpu);
633+
pr_debug("Cache Setup: find cache levels for CPU=%d\n", cpu);
613634

614635
acpi_cpu_id = get_acpi_id_for_cpu(cpu);
615636
cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
616-
if (cpu_node)
617-
number_of_levels = acpi_count_levels(table, cpu_node);
637+
if (!cpu_node)
638+
return -ENOENT;
618639

619-
pr_debug("Cache Setup find last level level=%d\n", number_of_levels);
640+
acpi_count_levels(table, cpu_node, levels, split_levels);
620641

621-
return number_of_levels;
642+
pr_debug("Cache Setup: last_level=%d split_levels=%d\n",
643+
*levels, split_levels ? *split_levels : -1);
644+
645+
return 0;
622646
}
623647

624648
/**

include/linux/cacheinfo.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,22 @@ bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y);
8888
int detect_cache_attributes(unsigned int cpu);
8989
#ifndef CONFIG_ACPI_PPTT
9090
/*
91-
* acpi_find_last_cache_level is only called on ACPI enabled
91+
* acpi_get_cache_info() is only called on ACPI enabled
9292
* platforms using the PPTT for topology. This means that if
9393
* the platform supports other firmware configuration methods
9494
* we need to stub out the call when ACPI is disabled.
9595
* ACPI enabled platforms not using PPTT won't be making calls
9696
* to this function so we need not worry about them.
9797
*/
98-
static inline int acpi_find_last_cache_level(unsigned int cpu)
98+
static inline
99+
int acpi_get_cache_info(unsigned int cpu,
100+
unsigned int *levels, unsigned int *split_levels)
99101
{
100102
return 0;
101103
}
102104
#else
103-
int acpi_find_last_cache_level(unsigned int cpu);
105+
int acpi_get_cache_info(unsigned int cpu,
106+
unsigned int *levels, unsigned int *split_levels);
104107
#endif
105108

106109
const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf);

0 commit comments

Comments
 (0)