[PATCH 9/9] powerpc: A new cache geometry aux vectors

Paul Clarke pc at us.ibm.com
Wed Jan 11 03:16:32 AEDT 2017


On 01/08/2017 05:31 PM, Benjamin Herrenschmidt wrote:
> This adds AUX vectors for the L1I,D, L2 and L3 cache levels
> providing for each cache level the size of the cache in bytes
> and the geometry (line size and number of ways).
>
> We chose to not use the existing alpha/sh definition which
> packs all the information in a single entry per cache level as
> it is too restricted to represent some of the geometries used
> on POWER.

> diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
> index 3987bd9..1557d26 100644
> --- a/arch/powerpc/include/asm/cache.h
> +++ b/arch/powerpc/include/asm/cache.h
> @@ -35,6 +35,7 @@ struct ppc_cache_info {
>  	u32 log_block_size;
>  	u32 blocks_per_page;
>  	u32 sets;
> +	u32 assoc;

Associativity is defined as u32...

>  };
>
>  struct ppc64_caches {
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 730c27e..a128836 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h

> +extern long il1cache_shape;
> +extern long dl1cache_shape;
> +extern long l2cache_shape;
> +extern long l3cache_shape;

shapes are "long"...

> @@ -136,6 +140,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
>
>  #endif /* CONFIG_SPU_BASE */
>
> +#define get_cache_shape(level) \
> +	(ppc64_caches.level.assoc << 16 | ppc64_caches.level.line_size)

Now we stuff u32 assoc into 16 bits.

What's the reason behind combining associativity and cache line size into a single field?

Likely the most requested values will be cache line size and (maybe) cache size.  The latter is a simple query with these changes, but the former is now a query and some awkward mask/shift.  I don't think we're currently providing accessor macros, although I guess those can be added to glibc.  Would it not be simpler, though, to just add independent queries for each of cache line size and associativity?
- AT_L1I_CACHESIZE
- AT_L1I_CACHE_LINE_SIZE
- AT_L1I_CACHE_ASSOC
etc.

Is there a big "con" to having a few more AUXV entries?

Regards,
PC

> @@ -156,6 +163,14 @@ do {									\
>  	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
>  	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
>  	VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base);	\
> +	NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);		\
> +	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, get_cache_shape(l1i));	\
> +	NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1i.size);		\
> +	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_shape(l1i));	\
> +	NEW_AUX_ENT(AT_L2_CACHESIZE, ppc64_caches.l2.size);		\
> +	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, get_cache_shape(l2));		\
> +	NEW_AUX_ENT(AT_L3_CACHESIZE, ppc64_caches.l3.size);		\
> +	NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, get_cache_shape(l3));		\
>  } while (0)
>
>  #endif /* _ASM_POWERPC_ELF_H */
> diff --git a/arch/powerpc/include/uapi/asm/auxvec.h b/arch/powerpc/include/uapi/asm/auxvec.h
> index ce17d2c..be6e94e 100644
> --- a/arch/powerpc/include/uapi/asm/auxvec.h
> +++ b/arch/powerpc/include/uapi/asm/auxvec.h
> @@ -16,6 +16,37 @@
>   */
>  #define AT_SYSINFO_EHDR		33
>
> -#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
> +/*
> + * AT_*CACHEBSIZE above represent the cache *block* size which is
> + * the size that is affected by the cache management instructions.
> + *
> + * It doesn't nececssarily matches the cache *line* size which is
> + * more of a performance tuning hint. Additionally the latter can
> + * be different for the different cache levels.
> + *
> + * The set of entries below represent more extensive information
> + * about the caches, in the form of two entry per cache type,
> + * one entry containing the cache size in bytes, and the other
> + * containing the cache line size in bytes in the bottom 16 bits
> + * and the cache associativity in the next 16 bits.
> + *
> + * The associativity is such that if N is the 16-bit value, the
> + * cache is N way set associative. A value if 0xffff means fully
> + * associative, a value of 1 means directly mapped.
> + *
> + * For all these fields, a value of 0 means that the information
> + * is not known.
> + */
> +
> +#define AT_L1I_CACHESIZE	40
> +#define AT_L1I_CACHEGEOMETRY	41
> +#define AT_L1D_CACHESIZE	42
> +#define AT_L1D_CACHEGEOMETRY	43
> +#define AT_L2_CACHESIZE		44
> +#define AT_L2_CACHEGEOMETRY	45
> +#define AT_L3_CACHESIZE		46
> +#define AT_L3_CACHEGEOMETRY	47
> +
> +#define AT_VECTOR_SIZE_ARCH	14 /* entries in ARCH_DLINFO */
>
>  #endif
> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> index e0eeed4..cfa2a06 100644
> --- a/arch/powerpc/kernel/setup-common.c
> +++ b/arch/powerpc/kernel/setup-common.c
> @@ -94,7 +94,10 @@ EXPORT_SYMBOL_GPL(boot_cpuid);
>  int dcache_bsize;
>  int icache_bsize;
>  int ucache_bsize;
> -
> +long il1cache_shape = -1;
> +long dl1cache_shape = -1;
> +long l2cache_shape = -1;
> +long l3cache_shape = -1;
>
>  unsigned long klimit = (unsigned long) _end;
>
> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
> index b3c93d8..16cb0b7 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -451,6 +451,10 @@ static bool __init parse_cache_info(struct device_node *np,
>  	info->block_size = bsize;
>  	info->log_block_size = __ilog2(bsize);
>  	info->blocks_per_page = PAGE_SIZE / bsize;
> +	if (sets == 0)
> +		info->assoc = 0xffff;
> +	else
> +		info->assoc = size / (sets * lsize);
>
>  	return success;
>  }
>



More information about the Linuxppc-dev mailing list