Skip to content

Commit

Permalink
powerpc: Fix missing L2 cache size in /sys/devices/system/cpu
Browse files Browse the repository at this point in the history
This problem appears to have been introduced in 2.6.29 by commit
93197a3 "Rewrite sysfs processor cache info code".

This caused lscpu to error out on at least e500v2 devices, eg:

  error: cannot open /sys/devices/system/cpu/cpu0/cache/index2/size: No such file or directory

Some embedded powerpc systems use cache-size in DTS for the unified L2
cache size, not d-cache-size, so we need to allow for both DTS names.
Added a new CACHE_TYPE_UNIFIED_D cache_type_info structure to handle
this.

Fixes: 93197a3 ("powerpc: Rewrite sysfs processor cache info code")
Signed-off-by: Dave Olson <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
  • Loading branch information
Dave Olson authored and mpe committed Apr 11, 2015
1 parent c54b2bf commit f7e9e35
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions arch/powerpc/kernel/cacheinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,21 @@ struct cache_type_info {
};

/* These are used to index the cache_type_info array. */
#define CACHE_TYPE_UNIFIED 0
#define CACHE_TYPE_INSTRUCTION 1
#define CACHE_TYPE_DATA 2
#define CACHE_TYPE_UNIFIED 0 /* cache-size, cache-block-size, etc. */
#define CACHE_TYPE_UNIFIED_D 1 /* d-cache-size, d-cache-block-size, etc */
#define CACHE_TYPE_INSTRUCTION 2
#define CACHE_TYPE_DATA 3

static const struct cache_type_info cache_type_info[] = {
{
/* Embedded systems that use cache-size, cache-block-size,
* etc. for the Unified (typically L2) cache. */
.name = "Unified",
.size_prop = "cache-size",
.line_size_props = { "cache-line-size",
"cache-block-size", },
.nr_sets_prop = "cache-sets",
},
{
/* PowerPC Processor binding says the [di]-cache-*
* must be equal on unified caches, so just use
Expand Down Expand Up @@ -293,7 +303,8 @@ static struct cache *cache_find_first_sibling(struct cache *cache)
{
struct cache *iter;

if (cache->type == CACHE_TYPE_UNIFIED)
if (cache->type == CACHE_TYPE_UNIFIED ||
cache->type == CACHE_TYPE_UNIFIED_D)
return cache;

list_for_each_entry(iter, &cache_list, list)
Expand Down Expand Up @@ -324,16 +335,29 @@ static bool cache_node_is_unified(const struct device_node *np)
return of_get_property(np, "cache-unified", NULL);
}

static struct cache *cache_do_one_devnode_unified(struct device_node *node,
int level)
/*
* Unified caches can have two different sets of tags. Most embedded
* use cache-size, etc. for the unified cache size, but open firmware systems
* use d-cache-size, etc. Check on initialization for which type we have, and
* return the appropriate structure type. Assume it's embedded if it isn't
* open firmware. If it's yet a 3rd type, then there will be missing entries
* in /sys/devices/system/cpu/cpu0/cache/index2/, and this code will need
* to be extended further.
*/
static int cache_is_unified_d(const struct device_node *np)
{
struct cache *cache;
return of_get_property(np,
cache_type_info[CACHE_TYPE_UNIFIED_D].size_prop, NULL) ?
CACHE_TYPE_UNIFIED_D : CACHE_TYPE_UNIFIED;
}

/*
*/
static struct cache *cache_do_one_devnode_unified(struct device_node *node, int level)
{
pr_debug("creating L%d ucache for %s\n", level, node->full_name);

cache = new_cache(CACHE_TYPE_UNIFIED, level, node);

return cache;
return new_cache(cache_is_unified_d(node), level, node);
}

static struct cache *cache_do_one_devnode_split(struct device_node *node,
Expand Down

0 comments on commit f7e9e35

Please sign in to comment.