All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi
@ 2017-01-08 23:31 Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 2/9] powerpc: Move {d, i, u}cache_bsize definitions to a common place Benjamin Herrenschmidt
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

It's an kernel private macro, it doesn't belong there

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/elf.h      | 22 ++++++++++++++++++++++
 arch/powerpc/include/uapi/asm/elf.h | 23 -----------------------
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index ee46ffe..730c27e 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -136,4 +136,26 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #endif /* CONFIG_SPU_BASE */
 
+/*
+ * The requirements here are:
+ * - keep the final alignment of sp (sp & 0xf)
+ * - make sure the 32-bit value at the first 16 byte aligned position of
+ *   AUXV is greater than 16 for glibc compatibility.
+ *   AT_IGNOREPPC is used for that.
+ * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+ *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
+ */
+#define ARCH_DLINFO							\
+do {									\
+	/* Handle glibc compatibility. */				\
+	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+	/* Cache size items */						\
+	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
+	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);	\
+} while (0)
+
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 3a9e44c..b2c6fdd 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -162,29 +162,6 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
 typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
 #endif
 
-
-/*
- * The requirements here are:
- * - keep the final alignment of sp (sp & 0xf)
- * - make sure the 32-bit value at the first 16 byte aligned position of
- *   AUXV is greater than 16 for glibc compatibility.
- *   AT_IGNOREPPC is used for that.
- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
- *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
- * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
- */
-#define ARCH_DLINFO							\
-do {									\
-	/* Handle glibc compatibility. */				\
-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
-	/* Cache size items */						\
-	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
-	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);	\
-} while (0)
-
 /* PowerPC64 relocations defined by the ABIs */
 #define R_PPC64_NONE    R_PPC_NONE
 #define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/9] powerpc: Move {d, i, u}cache_bsize definitions to a common place
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 3/9] powerpc: Remove obsolete comment about patching instructions Benjamin Herrenschmidt
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

The variables are defined twice in setup_32.c and setup_64.c, do it
once in setup-common.c instead

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/setup-common.c | 9 +++++++++
 arch/powerpc/kernel/setup_32.c     | 8 --------
 arch/powerpc/kernel/setup_64.c     | 8 --------
 3 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index dba265c..e0eeed4 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -87,6 +87,15 @@ EXPORT_SYMBOL(machine_id);
 int boot_cpuid = -1;
 EXPORT_SYMBOL_GPL(boot_cpuid);
 
+/*
+ * These are used in binfmt_elf.c to put aux entries on the stack
+ * for each elf executable being started.
+ */
+int dcache_bsize;
+int icache_bsize;
+int ucache_bsize;
+
+
 unsigned long klimit = (unsigned long) _end;
 
 /*
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 24ec3ea..3b81742 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -53,14 +53,6 @@ unsigned int DMA_MODE_READ;
 unsigned int DMA_MODE_WRITE;
 
 /*
- * These are used in binfmt_elf.c to put aux entries on the stack
- * for each elf executable being started.
- */
-int dcache_bsize;
-int icache_bsize;
-int ucache_bsize;
-
-/*
  * We're called here very early in the boot.
  *
  * Note that the kernel may be running at an address which is different
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 7ac8e6e..6263e0d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -88,14 +88,6 @@ struct ppc64_caches ppc64_caches = {
 };
 EXPORT_SYMBOL_GPL(ppc64_caches);
 
-/*
- * These are used in binfmt_elf.c to put aux entries on the stack
- * for each elf executable being started.
- */
-int dcache_bsize;
-int icache_bsize;
-int ucache_bsize;
-
 #if defined(CONFIG_PPC_BOOK3E) && defined(CONFIG_SMP)
 void __init setup_tlb_core_data(void)
 {
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/9] powerpc: Remove obsolete comment about patching instructions
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 2/9] powerpc: Move {d, i, u}cache_bsize definitions to a common place Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 4/9] powerpc/64: Fix naming of cache block vs. cache line Benjamin Herrenschmidt
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

We don't patch instructions based on the cache lines or block
sizes these days.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/setup_64.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 6263e0d..222bbb0 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -77,9 +77,6 @@
 int spinning_secondaries;
 u64 ppc64_pft_size;
 
-/* Pick defaults since we might want to patch instructions
- * before we've read this from the device tree.
- */
 struct ppc64_caches ppc64_caches = {
 	.dline_size = 0x40,
 	.log_dline_size = 6,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/9] powerpc/64: Fix naming of cache block vs. cache line
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 2/9] powerpc: Move {d, i, u}cache_bsize definitions to a common place Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 3/9] powerpc: Remove obsolete comment about patching instructions Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 5/9] powerpc/64: Retrieve number of L1 cache sets from device-tree Benjamin Herrenschmidt
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

In a number of places we called "cache line size" what is actually
the cache block size, which in the powerpc architecture, means the
effective size to use with cache management instructions (it can
be different from the actual cache line size).

We fix the naming across the board and properly retrieve both
pieces of information when available in the device-tree.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/cache.h   | 12 ++++---
 arch/powerpc/include/asm/page_64.h |  4 +--
 arch/powerpc/kernel/align.c        |  2 +-
 arch/powerpc/kernel/asm-offsets.c  | 12 +++----
 arch/powerpc/kernel/misc_64.S      | 28 ++++++++--------
 arch/powerpc/kernel/setup_64.c     | 65 +++++++++++++++++++++-----------------
 arch/powerpc/kernel/vdso.c         | 10 +++---
 arch/powerpc/lib/copypage_64.S     |  4 +--
 arch/powerpc/lib/string_64.S       |  6 ++--
 9 files changed, 75 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index ffbafbf..c74ebc2 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -30,12 +30,14 @@
 struct ppc64_caches {
 	u32	dsize;			/* L1 d-cache size */
 	u32	dline_size;		/* L1 d-cache line size	*/
-	u32	log_dline_size;
-	u32	dlines_per_page;
+	u32	dblock_size;		/* L1 d-cache block size */
+	u32	log_dblock_size;
+	u32	dblocks_per_page;
 	u32	isize;			/* L1 i-cache size */
-	u32	iline_size;		/* L1 i-cache line size	*/
-	u32	log_iline_size;
-	u32	ilines_per_page;
+	u32	iline_size;		/* L1 d-cache line size	*/
+	u32	iblock_size;		/* L1 i-cache block size */
+	u32	log_iblock_size;
+	u32	iblocks_per_page;
 };
 
 extern struct ppc64_caches ppc64_caches;
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index dd5f071..c50a666 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -47,14 +47,14 @@ static inline void clear_page(void *addr)
 	unsigned long iterations;
 	unsigned long onex, twox, fourx, eightx;
 
-	iterations = ppc64_caches.dlines_per_page / 8;
+	iterations = ppc64_caches.dblocks_per_page / 8;
 
 	/*
 	 * Some verisions of gcc use multiply instructions to
 	 * calculate the offsets so lets give it a hand to
 	 * do better.
 	 */
-	onex = ppc64_caches.dline_size;
+	onex = ppc64_caches.dblock_size;
 	twox = onex << 1;
 	fourx = onex << 2;
 	eightx = onex << 3;
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 033f338..a617751 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -204,7 +204,7 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
 	int i, size;
 
 #ifdef __powerpc64__
-	size = ppc64_caches.dline_size;
+	size = ppc64_caches.dblock_size;
 #else
 	size = L1_CACHE_BYTES;
 #endif
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index b89d14c..e2a881f 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -160,12 +160,12 @@ int main(void)
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
 
 #ifdef CONFIG_PPC64
-	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
-	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
-	DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
-	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
-	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
-	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
+	DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, dblock_size));
+	DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_dblock_size));
+	DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, dblocks_per_page));
+	DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, iblock_size));
+	DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_iblock_size));
+	DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, iblocks_per_page));
 	/* paca */
 	DEFINE(PACA_SIZE, sizeof(struct paca_struct));
 	DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index cb19515..70bc6f1 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -79,12 +79,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
  * each other.
  */
  	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
+	lwz	r7,DCACHEL1BLOCKSIZE(r10)/* Get cache block size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */
+	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of cache block size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -95,12 +95,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 
 /* Now invalidate the instruction cache */
 	
-	lwz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */
+	lwz	r7,ICACHEL1BLOCKSIZE(r10)	/* Get Icache block size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5
-	lwz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */
+	lwz	r9,ICACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of Icache block size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -125,12 +125,12 @@ _GLOBAL(flush_dcache_range)
  * Different systems have different cache line sizes
  */
  	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
+	lwz	r7,DCACHEL1BLOCKSIZE(r10)	/* Get dcache block size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
+	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of dcache block size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mtctr	r8
@@ -152,12 +152,12 @@ _GLOBAL(flush_dcache_range)
  */
 _GLOBAL(flush_dcache_phys_range)
  	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
+	lwz	r7,DCACHEL1BLOCKSIZE(r10)	/* Get dcache block size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
+	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)	/* Get log-2 of dcache block size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	mfmsr	r5			/* Disable MMU Data Relocation */
@@ -180,12 +180,12 @@ _GLOBAL(flush_dcache_phys_range)
 
 _GLOBAL(flush_inval_dcache_range)
  	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
+	lwz	r7,DCACHEL1BLOCKSIZE(r10)	/* Get dcache block size */
 	addi	r5,r7,-1
 	andc	r6,r3,r5		/* round low to line bdy */
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */
+	lwz	r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache block size */
 	srw.	r8,r8,r9		/* compute line count */
 	beqlr				/* nothing to do? */
 	sync
@@ -221,8 +221,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 /* Flush the dcache */
  	ld	r7,PPC64_CACHES@toc(r2)
 	clrrdi	r3,r3,PAGE_SHIFT           	    /* Page align */
-	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
-	lwz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
+	lwz	r4,DCACHEL1BLOCKSPERPAGE(r7)	/* Get # dcache blocks per page */
+	lwz	r5,DCACHEL1BLOCKSIZE(r7)	/* Get dcache block size */
 	mr	r6,r3
 	mtctr	r4
 0:	dcbst	0,r6
@@ -232,8 +232,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 
 /* Now invalidate the icache */	
 
-	lwz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
-	lwz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */
+	lwz	r4,ICACHEL1BLOCKSPERPAGE(r7)	/* Get # icache blocks per page */
+	lwz	r5,ICACHEL1BLOCKSIZE(r7)	/* Get icache block size */
 	mtctr	r4
 1:	icbi	0,r3
 	add	r3,r3,r5
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 222bbb0..e7e5c1b 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -78,10 +78,10 @@ int spinning_secondaries;
 u64 ppc64_pft_size;
 
 struct ppc64_caches ppc64_caches = {
-	.dline_size = 0x40,
-	.log_dline_size = 6,
-	.iline_size = 0x40,
-	.log_iline_size = 6
+	.dblock_size = 0x40,
+	.log_dblock_size = 6,
+	.iblock_size = 0x40,
+	.log_iblock_size = 6
 };
 EXPORT_SYMBOL_GPL(ppc64_caches);
 
@@ -404,59 +404,66 @@ void __init initialize_cache_info(void)
 		 * d-cache and i-cache sizes... -Peter
 		 */
 		if (num_cpus == 1) {
-			const __be32 *sizep, *lsizep;
-			u32 size, lsize;
+			const __be32 *sizep, *lsizep, *bsizep;
+			u32 size, lsize, bsize;
 
 			size = 0;
-			lsize = cur_cpu_spec->dcache_bsize;
+			lsize = bsize = cur_cpu_spec->dcache_bsize;
 			sizep = of_get_property(np, "d-cache-size", NULL);
 			if (sizep != NULL)
 				size = be32_to_cpu(*sizep);
-			lsizep = of_get_property(np, "d-cache-block-size",
+			bsizep = of_get_property(np, "d-cache-block-size",
 						 NULL);
-			/* fallback if block size missing */
-			if (lsizep == NULL)
-				lsizep = of_get_property(np,
-							 "d-cache-line-size",
-							 NULL);
+			lsizep = of_get_property(np, "d-cache-line-size",
+						 NULL);
+			if (bsizep == NULL)
+				bsizep = lsizep;
 			if (lsizep != NULL)
 				lsize = be32_to_cpu(*lsizep);
-			if (sizep == NULL || lsizep == NULL)
+			if (bsizep != NULL)
+				bsize = be32_to_cpu(*bsizep);
+			if (sizep == NULL || bsizep == NULL || lsizep == NULL)
 				DBG("Argh, can't find dcache properties ! "
-				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
+				    "sizep: %p, bsizep: %p, lsizep: %p\n",
+				    sizep, bsizep, lsizep);
 
 			ppc64_caches.dsize = size;
 			ppc64_caches.dline_size = lsize;
-			ppc64_caches.log_dline_size = __ilog2(lsize);
-			ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
+			ppc64_caches.dblock_size = bsize;
+			ppc64_caches.log_dblock_size = __ilog2(bsize);
+			ppc64_caches.dblocks_per_page = PAGE_SIZE / bsize;
 
 			size = 0;
-			lsize = cur_cpu_spec->icache_bsize;
+			lsize = bsize = cur_cpu_spec->icache_bsize;
 			sizep = of_get_property(np, "i-cache-size", NULL);
 			if (sizep != NULL)
 				size = be32_to_cpu(*sizep);
-			lsizep = of_get_property(np, "i-cache-block-size",
+			bsizep = of_get_property(np, "i-cache-block-size",
+						 NULL);
+			lsizep = of_get_property(np, "i-cache-line-size",
 						 NULL);
-			if (lsizep == NULL)
-				lsizep = of_get_property(np,
-							 "i-cache-line-size",
-							 NULL);
+			if (bsizep == NULL)
+				bsizep = lsizep;
 			if (lsizep != NULL)
 				lsize = be32_to_cpu(*lsizep);
-			if (sizep == NULL || lsizep == NULL)
+			if (bsizep != NULL)
+				bsize = be32_to_cpu(*bsizep);
+			if (sizep == NULL || bsizep == NULL || lsizep == NULL)
 				DBG("Argh, can't find icache properties ! "
-				    "sizep: %p, lsizep: %p\n", sizep, lsizep);
+				    "sizep: %p, bsizep: %p, lsizep: %p\n",
+				    sizep, bsizep, lsizep);
 
 			ppc64_caches.isize = size;
 			ppc64_caches.iline_size = lsize;
-			ppc64_caches.log_iline_size = __ilog2(lsize);
-			ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
+			ppc64_caches.iblock_size = bsize;
+			ppc64_caches.log_iblock_size = __ilog2(bsize);
+			ppc64_caches.iblocks_per_page = PAGE_SIZE / bsize;
 		}
 	}
 
 	/* For use by binfmt_elf */
-	dcache_bsize = ppc64_caches.dline_size;
-	icache_bsize = ppc64_caches.iline_size;
+	dcache_bsize = ppc64_caches.dblock_size;
+	icache_bsize = ppc64_caches.iblock_size;
 
 	DBG(" <- initialize_cache_info()\n");
 }
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 4111d30..9c0a857 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -740,12 +740,10 @@ static int __init vdso_init(void)
 	vdso_data->dcache_line_size = ppc64_caches.dline_size;
 	vdso_data->icache_size = ppc64_caches.isize;
 	vdso_data->icache_line_size = ppc64_caches.iline_size;
-
-	/* XXXOJN: Blocks should be added to ppc64_caches and used instead */
-	vdso_data->dcache_block_size = ppc64_caches.dline_size;
-	vdso_data->icache_block_size = ppc64_caches.iline_size;
-	vdso_data->dcache_log_block_size = ppc64_caches.log_dline_size;
-	vdso_data->icache_log_block_size = ppc64_caches.log_iline_size;
+	vdso_data->dcache_block_size = ppc64_caches.dblock_size;
+	vdso_data->icache_block_size = ppc64_caches.iblock_size;
+	vdso_data->dcache_log_block_size = ppc64_caches.log_dblock_size;
+	vdso_data->icache_log_block_size = ppc64_caches.log_iblock_size;
 
 	/*
 	 * Calculate the size of the 64 bits vDSO
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S
index a3c4dc4..0c3bd46 100644
--- a/arch/powerpc/lib/copypage_64.S
+++ b/arch/powerpc/lib/copypage_64.S
@@ -25,8 +25,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
 	ori	r5,r5,PAGE_SIZE@l
 BEGIN_FTR_SECTION
 	ld      r10,PPC64_CACHES@toc(r2)
-	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
-	lwz     r12,DCACHEL1LINESIZE(r10)	/* get cache line size */
+	lwz	r11,DCACHEL1LOGBLOCKSIZE(r10)	/* log2 of cache block size */
+	lwz     r12,DCACHEL1BLOCKSIZE(r10)	/* get cache block size */
 	li	r9,0
 	srd	r8,r5,r11
 
diff --git a/arch/powerpc/lib/string_64.S b/arch/powerpc/lib/string_64.S
index 7bd9549..9907379 100644
--- a/arch/powerpc/lib/string_64.S
+++ b/arch/powerpc/lib/string_64.S
@@ -159,9 +159,9 @@ err2;	std	r0,0(r3)
 	addi	r3,r3,8
 	addi	r4,r4,-8
 
-	/* Destination is 16 byte aligned, need to get it cacheline aligned */
-11:	lwz	r7,DCACHEL1LOGLINESIZE(r5)
-	lwz	r9,DCACHEL1LINESIZE(r5)
+	/* Destination is 16 byte aligned, need to get it cache block aligned */
+11:	lwz	r7,DCACHEL1LOGBLOCKSIZE(r5)
+	lwz	r9,DCACHEL1BLOCKSIZE(r5)
 
 	/*
 	 * With worst case alignment the long clear loop takes a minimum
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/9] powerpc/64: Retrieve number of L1 cache sets from device-tree
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
                   ` (2 preceding siblings ...)
  2017-01-08 23:31 ` [PATCH 4/9] powerpc/64: Fix naming of cache block vs. cache line Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 6/9] powerpc/64: Clean up ppc64_caches using a struct per cache Benjamin Herrenschmidt
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

It will be used to calculate the associativity

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/cache.h |  2 ++
 arch/powerpc/kernel/setup_64.c   | 27 +++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index c74ebc2..ceb1244 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -33,11 +33,13 @@ struct ppc64_caches {
 	u32	dblock_size;		/* L1 d-cache block size */
 	u32	log_dblock_size;
 	u32	dblocks_per_page;
+	u32	dsets;
 	u32	isize;			/* L1 i-cache size */
 	u32	iline_size;		/* L1 d-cache line size	*/
 	u32	iblock_size;		/* L1 i-cache block size */
 	u32	log_iblock_size;
 	u32	iblocks_per_page;
+	u32	isets;
 };
 
 extern struct ppc64_caches ppc64_caches;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e7e5c1b..d36b6f4 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -404,14 +404,18 @@ void __init initialize_cache_info(void)
 		 * d-cache and i-cache sizes... -Peter
 		 */
 		if (num_cpus == 1) {
-			const __be32 *sizep, *lsizep, *bsizep;
-			u32 size, lsize, bsize;
+			const __be32 *sizep, *lsizep, *bsizep, *setsp;
+			u32 size, lsize, bsize, sets;
 
 			size = 0;
+			sets = -1u;
 			lsize = bsize = cur_cpu_spec->dcache_bsize;
 			sizep = of_get_property(np, "d-cache-size", NULL);
 			if (sizep != NULL)
 				size = be32_to_cpu(*sizep);
+			setsp = of_get_property(np, "d-cache-sets", NULL);
+			if (setsp != NULL)
+				sets = be32_to_cpu(*setsp);
 			bsizep = of_get_property(np, "d-cache-block-size",
 						 NULL);
 			lsizep = of_get_property(np, "d-cache-line-size",
@@ -427,17 +431,31 @@ void __init initialize_cache_info(void)
 				    "sizep: %p, bsizep: %p, lsizep: %p\n",
 				    sizep, bsizep, lsizep);
 
+			/* OF is weird .. it represents fully associative caches
+			 * as "1 way" which doesn't make much sense and doesn't
+			 * leave room for direct mapped. We'll assume that 0
+			 * in OF means direct mapped for that reason.
+			 */
+			if (sets == 1)
+				sets = 0;
+			else if (sets == 0)
+				sets = 1;
 			ppc64_caches.dsize = size;
+			ppc64_caches.dsets = sets;
 			ppc64_caches.dline_size = lsize;
 			ppc64_caches.dblock_size = bsize;
 			ppc64_caches.log_dblock_size = __ilog2(bsize);
 			ppc64_caches.dblocks_per_page = PAGE_SIZE / bsize;
 
 			size = 0;
+			sets = -1u;
 			lsize = bsize = cur_cpu_spec->icache_bsize;
 			sizep = of_get_property(np, "i-cache-size", NULL);
 			if (sizep != NULL)
 				size = be32_to_cpu(*sizep);
+			setsp = of_get_property(np, "i-cache-sets", NULL);
+			if (setsp != NULL)
+				sets = be32_to_cpu(*setsp);
 			bsizep = of_get_property(np, "i-cache-block-size",
 						 NULL);
 			lsizep = of_get_property(np, "i-cache-line-size",
@@ -453,7 +471,12 @@ void __init initialize_cache_info(void)
 				    "sizep: %p, bsizep: %p, lsizep: %p\n",
 				    sizep, bsizep, lsizep);
 
+			if (sets == 1)
+				sets = 0;
+			else if (sets == 0)
+				sets = 1;
 			ppc64_caches.isize = size;
+			ppc64_caches.isets = sets;
 			ppc64_caches.iline_size = lsize;
 			ppc64_caches.iblock_size = bsize;
 			ppc64_caches.log_iblock_size = __ilog2(bsize);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/9] powerpc/64: Clean up ppc64_caches using a struct per cache
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
                   ` (3 preceding siblings ...)
  2017-01-08 23:31 ` [PATCH 5/9] powerpc/64: Retrieve number of L1 cache sets from device-tree Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 7/9] powerpc/64: Add L2 and L3 cache shape info Benjamin Herrenschmidt
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

We have two set of identical struct members for the I and D sides
and mostly identical bunches of code to parse the device-tree to
populate them. Instead make a ppc_cache_info structure with one
copy for I and one for D

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/cache.h   |  24 ++---
 arch/powerpc/include/asm/page_64.h |   4 +-
 arch/powerpc/kernel/align.c        |   2 +-
 arch/powerpc/kernel/asm-offsets.c  |  12 +--
 arch/powerpc/kernel/setup_64.c     | 175 ++++++++++++++++++-------------------
 arch/powerpc/kernel/vdso.c         |  16 ++--
 6 files changed, 112 insertions(+), 121 deletions(-)

diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index ceb1244..ceb7376 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -27,19 +27,19 @@
 #define	SMP_CACHE_BYTES		L1_CACHE_BYTES
 
 #if defined(__powerpc64__) && !defined(__ASSEMBLY__)
+
+struct ppc_cache_info {
+	u32 size;
+	u32 line_size;
+	u32 block_size;	/* L1 only */
+	u32 log_block_size;
+	u32 blocks_per_page;
+	u32 sets;
+};
+
 struct ppc64_caches {
-	u32	dsize;			/* L1 d-cache size */
-	u32	dline_size;		/* L1 d-cache line size	*/
-	u32	dblock_size;		/* L1 d-cache block size */
-	u32	log_dblock_size;
-	u32	dblocks_per_page;
-	u32	dsets;
-	u32	isize;			/* L1 i-cache size */
-	u32	iline_size;		/* L1 d-cache line size	*/
-	u32	iblock_size;		/* L1 i-cache block size */
-	u32	log_iblock_size;
-	u32	iblocks_per_page;
-	u32	isets;
+	struct ppc_cache_info l1d;
+	struct ppc_cache_info l1i;
 };
 
 extern struct ppc64_caches ppc64_caches;
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index c50a666..3e83d2a 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -47,14 +47,14 @@ static inline void clear_page(void *addr)
 	unsigned long iterations;
 	unsigned long onex, twox, fourx, eightx;
 
-	iterations = ppc64_caches.dblocks_per_page / 8;
+	iterations = ppc64_caches.l1d.blocks_per_page / 8;
 
 	/*
 	 * Some verisions of gcc use multiply instructions to
 	 * calculate the offsets so lets give it a hand to
 	 * do better.
 	 */
-	onex = ppc64_caches.dblock_size;
+	onex = ppc64_caches.l1d.block_size;
 	twox = onex << 1;
 	fourx = onex << 2;
 	eightx = onex << 3;
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index a617751..7806211 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -204,7 +204,7 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
 	int i, size;
 
 #ifdef __powerpc64__
-	size = ppc64_caches.dblock_size;
+	size = ppc64_caches.l1d.block_size;
 #else
 	size = L1_CACHE_BYTES;
 #endif
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index e2a881f..100261b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -160,12 +160,12 @@ int main(void)
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
 
 #ifdef CONFIG_PPC64
-	DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, dblock_size));
-	DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_dblock_size));
-	DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, dblocks_per_page));
-	DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, iblock_size));
-	DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_iblock_size));
-	DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, iblocks_per_page));
+	DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, l1d.block_size));
+	DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, l1d.log_block_size));
+	DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, l1d.blocks_per_page));
+	DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, l1i.block_size));
+	DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, l1i.log_block_size));
+	DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, l1i.blocks_per_page));
 	/* paca */
 	DEFINE(PACA_SIZE, sizeof(struct paca_struct));
 	DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index d36b6f4..e2946a7 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -78,10 +78,14 @@ int spinning_secondaries;
 u64 ppc64_pft_size;
 
 struct ppc64_caches ppc64_caches = {
-	.dblock_size = 0x40,
-	.log_dblock_size = 6,
-	.iblock_size = 0x40,
-	.log_iblock_size = 6
+	.l1d = {
+		.block_size = 0x40,
+		.log_block_size = 6,
+	},
+	.l1i = {
+		.block_size = 0x40,
+		.log_block_size = 6
+	},
 };
 EXPORT_SYMBOL_GPL(ppc64_caches);
 
@@ -389,104 +393,91 @@ void smp_release_cpus(void)
  * cache informations about the CPU that will be used by cache flush
  * routines and/or provided to userland
  */
+
+static bool __init parse_cache_info(struct device_node *np,
+				    bool icache,
+				    struct ppc_cache_info *info)
+{
+	static const char *ipropnames[] __initdata = {
+		"i-cache-size",
+		"i-cache-sets",
+		"i-cache-block-size",
+		"i-cache-line-size",
+	};
+	static const char *dpropnames[] __initdata = {
+		"d-cache-size",
+		"d-cache-sets",
+		"d-cache-block-size",
+		"d-cache-line-size",
+	};
+	const char **propnames = icache ? ipropnames : dpropnames;
+	const __be32 *sizep, *lsizep, *bsizep, *setsp;
+	u32 size, lsize, bsize, sets;
+	bool success = true;
+
+	size = 0;
+	sets = -1u;
+	lsize = bsize = cur_cpu_spec->dcache_bsize;
+	sizep = of_get_property(np, propnames[0], NULL);
+	if (sizep != NULL)
+		size = be32_to_cpu(*sizep);
+	setsp = of_get_property(np, propnames[1], NULL);
+	if (setsp != NULL)
+		sets = be32_to_cpu(*setsp);
+	bsizep = of_get_property(np, propnames[2], NULL);
+	lsizep = of_get_property(np, propnames[3], NULL);
+	if (bsizep == NULL)
+		bsizep = lsizep;
+	if (lsizep != NULL)
+		lsize = be32_to_cpu(*lsizep);
+	if (bsizep != NULL)
+		bsize = be32_to_cpu(*bsizep);
+	if (sizep == NULL || bsizep == NULL || lsizep == NULL)
+		success = false;
+
+	/* OF is weird .. it represents fully associative caches
+	 * as "1 way" which doesn't make much sense and doesn't
+	 * leave room for direct mapped. We'll assume that 0
+	 * in OF means direct mapped for that reason.
+	 */
+	if (sets == 1)
+		sets = 0;
+	else if (sets == 0)
+		sets = 1;
+
+	info->size = size;
+	info->sets = sets;
+	info->line_size = lsize;
+	info->block_size = bsize;
+	info->log_block_size = __ilog2(bsize);
+	info->blocks_per_page = PAGE_SIZE / bsize;
+
+	return success;
+}
+
 void __init initialize_cache_info(void)
 {
 	struct device_node *np;
-	unsigned long num_cpus = 0;
 
 	DBG(" -> initialize_cache_info()\n");
 
-	for_each_node_by_type(np, "cpu") {
-		num_cpus += 1;
+	np  = of_find_node_by_type(NULL, "cpu");
 
-		/*
-		 * We're assuming *all* of the CPUs have the same
-		 * d-cache and i-cache sizes... -Peter
-		 */
-		if (num_cpus == 1) {
-			const __be32 *sizep, *lsizep, *bsizep, *setsp;
-			u32 size, lsize, bsize, sets;
-
-			size = 0;
-			sets = -1u;
-			lsize = bsize = cur_cpu_spec->dcache_bsize;
-			sizep = of_get_property(np, "d-cache-size", NULL);
-			if (sizep != NULL)
-				size = be32_to_cpu(*sizep);
-			setsp = of_get_property(np, "d-cache-sets", NULL);
-			if (setsp != NULL)
-				sets = be32_to_cpu(*setsp);
-			bsizep = of_get_property(np, "d-cache-block-size",
-						 NULL);
-			lsizep = of_get_property(np, "d-cache-line-size",
-						 NULL);
-			if (bsizep == NULL)
-				bsizep = lsizep;
-			if (lsizep != NULL)
-				lsize = be32_to_cpu(*lsizep);
-			if (bsizep != NULL)
-				bsize = be32_to_cpu(*bsizep);
-			if (sizep == NULL || bsizep == NULL || lsizep == NULL)
-				DBG("Argh, can't find dcache properties ! "
-				    "sizep: %p, bsizep: %p, lsizep: %p\n",
-				    sizep, bsizep, lsizep);
-
-			/* OF is weird .. it represents fully associative caches
-			 * as "1 way" which doesn't make much sense and doesn't
-			 * leave room for direct mapped. We'll assume that 0
-			 * in OF means direct mapped for that reason.
-			 */
-			if (sets == 1)
-				sets = 0;
-			else if (sets == 0)
-				sets = 1;
-			ppc64_caches.dsize = size;
-			ppc64_caches.dsets = sets;
-			ppc64_caches.dline_size = lsize;
-			ppc64_caches.dblock_size = bsize;
-			ppc64_caches.log_dblock_size = __ilog2(bsize);
-			ppc64_caches.dblocks_per_page = PAGE_SIZE / bsize;
-
-			size = 0;
-			sets = -1u;
-			lsize = bsize = cur_cpu_spec->icache_bsize;
-			sizep = of_get_property(np, "i-cache-size", NULL);
-			if (sizep != NULL)
-				size = be32_to_cpu(*sizep);
-			setsp = of_get_property(np, "i-cache-sets", NULL);
-			if (setsp != NULL)
-				sets = be32_to_cpu(*setsp);
-			bsizep = of_get_property(np, "i-cache-block-size",
-						 NULL);
-			lsizep = of_get_property(np, "i-cache-line-size",
-						 NULL);
-			if (bsizep == NULL)
-				bsizep = lsizep;
-			if (lsizep != NULL)
-				lsize = be32_to_cpu(*lsizep);
-			if (bsizep != NULL)
-				bsize = be32_to_cpu(*bsizep);
-			if (sizep == NULL || bsizep == NULL || lsizep == NULL)
-				DBG("Argh, can't find icache properties ! "
-				    "sizep: %p, bsizep: %p, lsizep: %p\n",
-				    sizep, bsizep, lsizep);
-
-			if (sets == 1)
-				sets = 0;
-			else if (sets == 0)
-				sets = 1;
-			ppc64_caches.isize = size;
-			ppc64_caches.isets = sets;
-			ppc64_caches.iline_size = lsize;
-			ppc64_caches.iblock_size = bsize;
-			ppc64_caches.log_iblock_size = __ilog2(bsize);
-			ppc64_caches.iblocks_per_page = PAGE_SIZE / bsize;
-		}
+	/*
+	 * We're assuming *all* of the CPUs have the same
+	 * d-cache and i-cache sizes... -Peter
+	 */
+	if (np) {
+		if (!parse_cache_info(np, false, &ppc64_caches.l1d))
+			DBG("Argh, can't find dcache properties !\n");
+
+		if (!parse_cache_info(np, true, &ppc64_caches.l1i))
+			DBG("Argh, can't find icache properties !\n");
 	}
 
 	/* For use by binfmt_elf */
-	dcache_bsize = ppc64_caches.dblock_size;
-	icache_bsize = ppc64_caches.iblock_size;
+	dcache_bsize = ppc64_caches.l1d.block_size;
+	icache_bsize = ppc64_caches.l1i.block_size;
 
 	DBG(" <- initialize_cache_info()\n");
 }
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 9c0a857..22b01a3 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -736,14 +736,14 @@ static int __init vdso_init(void)
 	if (firmware_has_feature(FW_FEATURE_LPAR))
 		vdso_data->platform |= 1;
 	vdso_data->physicalMemorySize = memblock_phys_mem_size();
-	vdso_data->dcache_size = ppc64_caches.dsize;
-	vdso_data->dcache_line_size = ppc64_caches.dline_size;
-	vdso_data->icache_size = ppc64_caches.isize;
-	vdso_data->icache_line_size = ppc64_caches.iline_size;
-	vdso_data->dcache_block_size = ppc64_caches.dblock_size;
-	vdso_data->icache_block_size = ppc64_caches.iblock_size;
-	vdso_data->dcache_log_block_size = ppc64_caches.log_dblock_size;
-	vdso_data->icache_log_block_size = ppc64_caches.log_iblock_size;
+	vdso_data->dcache_size = ppc64_caches.l1d.size;
+	vdso_data->dcache_line_size = ppc64_caches.l1d.line_size;
+	vdso_data->icache_size = ppc64_caches.l1i.size;
+	vdso_data->icache_line_size = ppc64_caches.l1i.line_size;
+	vdso_data->dcache_block_size = ppc64_caches.l1d.block_size;
+	vdso_data->icache_block_size = ppc64_caches.l1i.block_size;
+	vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;
+	vdso_data->icache_log_block_size = ppc64_caches.l1i.log_block_size;
 
 	/*
 	 * Calculate the size of the 64 bits vDSO
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 7/9] powerpc/64: Add L2 and L3 cache shape info
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
                   ` (4 preceding siblings ...)
  2017-01-08 23:31 ` [PATCH 6/9] powerpc/64: Clean up ppc64_caches using a struct per cache Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 8/9] powerpc/64: Hard code cache geometry on POWER8 Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 9/9] powerpc: A new cache geometry aux vectors Benjamin Herrenschmidt
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

Retrieved from device-tree when available

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/cache.h |  2 ++
 arch/powerpc/kernel/setup_64.c   | 25 ++++++++++++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index ceb7376..3987bd9 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -40,6 +40,8 @@ struct ppc_cache_info {
 struct ppc64_caches {
 	struct ppc_cache_info l1d;
 	struct ppc_cache_info l1i;
+	struct ppc_cache_info l2;
+	struct ppc_cache_info l3;
 };
 
 extern struct ppc64_caches ppc64_caches;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e2946a7..216e305 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -457,22 +457,37 @@ static bool __init parse_cache_info(struct device_node *np,
 
 void __init initialize_cache_info(void)
 {
-	struct device_node *np;
+	struct device_node *cpu, *l2, *l3 = NULL;
 
 	DBG(" -> initialize_cache_info()\n");
 
-	np  = of_find_node_by_type(NULL, "cpu");
+	cpu = of_find_node_by_type(NULL, "cpu");
 
 	/*
 	 * We're assuming *all* of the CPUs have the same
 	 * d-cache and i-cache sizes... -Peter
 	 */
-	if (np) {
-		if (!parse_cache_info(np, false, &ppc64_caches.l1d))
+	if (cpu) {
+		if (!parse_cache_info(cpu, false, &ppc64_caches.l1d))
 			DBG("Argh, can't find dcache properties !\n");
 
-		if (!parse_cache_info(np, true, &ppc64_caches.l1i))
+		if (!parse_cache_info(cpu, true, &ppc64_caches.l1i))
 			DBG("Argh, can't find icache properties !\n");
+
+		/* Try to find the L2 and L3 if any. Assume they are
+		 * unified and use the D-side properties
+		 */
+		l2 = of_find_next_cache_node(cpu);
+		of_node_put(cpu);
+		if (l2) {
+			parse_cache_info(l2, false, &ppc64_caches.l2);
+			l3 = of_find_next_cache_node(l2);
+			of_node_put(l2);
+		}
+		if (l3) {
+			parse_cache_info(l3, false, &ppc64_caches.l3);
+			of_node_put(l3);
+		}
 	}
 
 	/* For use by binfmt_elf */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 8/9] powerpc/64: Hard code cache geometry on POWER8
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
                   ` (5 preceding siblings ...)
  2017-01-08 23:31 ` [PATCH 7/9] powerpc/64: Add L2 and L3 cache shape info Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-08 23:31 ` [PATCH 9/9] powerpc: A new cache geometry aux vectors Benjamin Herrenschmidt
  7 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

All shipping firmware versions have it wrong in the device-tree

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/setup_64.c | 52 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 216e305..b3c93d8 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -255,7 +255,7 @@ static void cpu_ready_for_interrupts(void)
 
 void __init early_setup(unsigned long dt_ptr)
 {
-	static __initdata struct paca_struct boot_paca;
+	static struct paca_struct boot_paca __initdata ;
 
 	/* -------- printk is _NOT_ safe to use here ! ------- */
 
@@ -455,13 +455,59 @@ static bool __init parse_cache_info(struct device_node *np,
 	return success;
 }
 
+static void __init populate_p8_cache_info(void)
+{
+	static const struct ppc_cache_info p8_l1i __initconst  = {
+		.size = 0x8000,
+		.line_size = 128,
+		.block_size = 128,
+		.log_block_size = 7,
+		.blocks_per_page = PAGE_SIZE / 128,
+		.sets = 32
+	};
+	static const struct ppc_cache_info p8_l1d __initconst  = {
+		.size = 0x10000,
+		.line_size = 128,
+		.block_size = 128,
+		.log_block_size = 7,
+		.blocks_per_page = PAGE_SIZE / 128,
+		.sets = 64
+	};
+	static const struct ppc_cache_info p8_l2 __initconst  = {
+		.size = 0x80000,
+		.line_size = 128,
+		.sets = 512
+	};
+	static const struct ppc_cache_info p8_l3 __initconst  = {
+		.size = 0x800000,
+		.line_size = 128,
+		.sets = 8192
+	};
+	ppc64_caches.l1i = p8_l1i;
+	ppc64_caches.l1d = p8_l1d;
+	ppc64_caches.l2 = p8_l2;
+	ppc64_caches.l3 = p8_l3;
+}
+
 void __init initialize_cache_info(void)
 {
-	struct device_node *cpu, *l2, *l3 = NULL;
+	struct device_node *cpu = NULL, *l2, *l3 = NULL;
+	u32 pvr;
 
 	DBG(" -> initialize_cache_info()\n");
 
-	cpu = of_find_node_by_type(NULL, "cpu");
+	/*
+	 * All shipping POWER8 machines have a firmware bug that
+	 * puts incorrect information in the device-tree. This will
+	 * be (hopefully) fixed for future chips but for now hard
+	 * code the values if we are running on one of these
+	 */
+	pvr = PVR_VER(mfspr(SPRN_PVR));
+	if (pvr == PVR_POWER8 || pvr == PVR_POWER8E ||
+	    pvr == PVR_POWER8NVL)
+		populate_p8_cache_info();
+	else
+		cpu = of_find_node_by_type(NULL, "cpu");
 
 	/*
 	 * We're assuming *all* of the CPUs have the same
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 9/9] powerpc: A new cache geometry aux vectors
  2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
                   ` (6 preceding siblings ...)
  2017-01-08 23:31 ` [PATCH 8/9] powerpc/64: Hard code cache geometry on POWER8 Benjamin Herrenschmidt
@ 2017-01-08 23:31 ` Benjamin Herrenschmidt
  2017-01-10 16:16   ` Paul Clarke
  2017-01-30 20:27   ` Michael Ellerman
  7 siblings, 2 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-08 23:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

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.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/cache.h       |  1 +
 arch/powerpc/include/asm/elf.h         | 17 ++++++++++++++++-
 arch/powerpc/include/uapi/asm/auxvec.h | 33 ++++++++++++++++++++++++++++++++-
 arch/powerpc/kernel/setup-common.c     |  5 ++++-
 arch/powerpc/kernel/setup_64.c         |  4 ++++
 5 files changed, 57 insertions(+), 3 deletions(-)

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;
 };
 
 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
@@ -108,13 +108,17 @@ do {								\
  */
 # define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \
 		(exec_stk == EXSTACK_DEFAULT) : 0)
-#else 
+#else
 # define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
 #endif /* __powerpc64__ */
 
 extern int dcache_bsize;
 extern int icache_bsize;
 extern int ucache_bsize;
+extern long il1cache_shape;
+extern long dl1cache_shape;
+extern long l2cache_shape;
+extern long l3cache_shape;
 
 /* vDSO has arch_setup_additional_pages */
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
@@ -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)
+
 /*
  * The requirements here are:
  * - keep the final alignment of sp (sp & 0xf)
@@ -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;
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 9/9] powerpc: A new cache geometry aux vectors
  2017-01-08 23:31 ` [PATCH 9/9] powerpc: A new cache geometry aux vectors Benjamin Herrenschmidt
@ 2017-01-10 16:16   ` Paul Clarke
  2017-01-10 16:26     ` Benjamin Herrenschmidt
  2017-01-30 20:27   ` Michael Ellerman
  1 sibling, 1 reply; 14+ messages in thread
From: Paul Clarke @ 2017-01-10 16:16 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, linuxppc-dev; +Cc: Steven Munroe

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;
>  }
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 9/9] powerpc: A new cache geometry aux vectors
  2017-01-10 16:16   ` Paul Clarke
@ 2017-01-10 16:26     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-10 16:26 UTC (permalink / raw)
  To: pc, linuxppc-dev; +Cc: Steven Munroe

On Tue, 2017-01-10 at 10:16 -0600, Paul Clarke wrote:
> 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"...

Those are obsolete definitions from the previous implementation, I
forgot to remove them.

> > @@ -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.

Right. Not a huge deal.

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

Because we are already creating way too many AT_* entries, I don't want
to add 4 more.

> 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.  

A simple mask, not *that* awkward.

> 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?

We already *multiplied* the number of arch entries and I think we're
the only arch to do that... at that point, I'm starting to prefer
something in the VDSO...

Ben.

> 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;
> >  }
> > 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 9/9] powerpc: A new cache geometry aux vectors
  2017-01-08 23:31 ` [PATCH 9/9] powerpc: A new cache geometry aux vectors Benjamin Herrenschmidt
  2017-01-10 16:16   ` Paul Clarke
@ 2017-01-30 20:27   ` Michael Ellerman
  2017-01-30 20:35     ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 14+ messages in thread
From: Michael Ellerman @ 2017-01-30 20:27 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, linuxppc-dev; +Cc: Steven Munroe

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/el=
f.h
> index 730c27e..a128836 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -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)
=20=20
This breaks the 32-bit build:


  ../fs/binfmt_elf.c: In function =E2=80=98create_elf_tables=E2=80=99:
  ../arch/powerpc/include/asm/elf.h:166:32: error: =E2=80=98ppc64_caches=E2=
=80=99 undeclared (first use in this function)
    NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);  \
                                  ^
  ../fs/binfmt_elf.c:222:26: note: in definition of macro =E2=80=98NEW_AUX_=
ENT=E2=80=99
     elf_info[ei_index++] =3D val; \
                            ^~~
  ../fs/binfmt_elf.c:232:2: note: in expansion of macro =E2=80=98ARCH_DLINF=
O=E2=80=99
    ARCH_DLINFO;
    ^~~~~~~~~~~
  ../arch/powerpc/include/asm/elf.h:166:32: note: each undeclared identifie=
r is reported only once for each function it appears in
    NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);  \
                                  ^
  ../fs/binfmt_elf.c:222:26: note: in definition of macro =E2=80=98NEW_AUX_=
ENT=E2=80=99
     elf_info[ei_index++] =3D val; \
                            ^~~
  ../fs/binfmt_elf.c:232:2: note: in expansion of macro =E2=80=98ARCH_DLINF=
O=E2=80=99
    ARCH_DLINFO;
    ^~~~~~~~~~~
  make[2]: *** [fs/binfmt_elf.o] Error 1
  make[2]: *** Waiting for unfinished jobs....
  make[1]: *** [fs] Error 2
  make: *** [sub-make] Error 2


Will need some more macro foo.

cheers

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 9/9] powerpc: A new cache geometry aux vectors
  2017-01-30 20:27   ` Michael Ellerman
@ 2017-01-30 20:35     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-30 20:35 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev; +Cc: Steven Munroe

On Tue, 2017-01-31 at 07:27 +1100, Michael Ellerman wrote:
> Will need some more macro foo.

That or make ppc64_caches ppc_caches, and make it common...

I'll look into it.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi
@ 2017-01-04  5:15 Benjamin Herrenschmidt
  0 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2017-01-04  5:15 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Munroe, Benjamin Herrenschmidt

It's an kernel private macro, it doesn't belong there

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/elf.h      | 22 ++++++++++++++++++++++
 arch/powerpc/include/uapi/asm/elf.h | 23 -----------------------
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index ee46ffe..730c27e 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -136,4 +136,26 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #endif /* CONFIG_SPU_BASE */
 
+/*
+ * The requirements here are:
+ * - keep the final alignment of sp (sp & 0xf)
+ * - make sure the 32-bit value at the first 16 byte aligned position of
+ *   AUXV is greater than 16 for glibc compatibility.
+ *   AT_IGNOREPPC is used for that.
+ * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+ *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
+ */
+#define ARCH_DLINFO							\
+do {									\
+	/* Handle glibc compatibility. */				\
+	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
+	/* Cache size items */						\
+	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
+	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);	\
+} while (0)
+
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 3a9e44c..b2c6fdd 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -162,29 +162,6 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
 typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
 #endif
 
-
-/*
- * The requirements here are:
- * - keep the final alignment of sp (sp & 0xf)
- * - make sure the 32-bit value at the first 16 byte aligned position of
- *   AUXV is greater than 16 for glibc compatibility.
- *   AT_IGNOREPPC is used for that.
- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
- *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
- * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
- */
-#define ARCH_DLINFO							\
-do {									\
-	/* Handle glibc compatibility. */				\
-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
-	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
-	/* Cache size items */						\
-	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
-	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);	\
-} while (0)
-
 /* PowerPC64 relocations defined by the ABIs */
 #define R_PPC64_NONE    R_PPC_NONE
 #define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2017-01-30 21:43 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 2/9] powerpc: Move {d, i, u}cache_bsize definitions to a common place Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 3/9] powerpc: Remove obsolete comment about patching instructions Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 4/9] powerpc/64: Fix naming of cache block vs. cache line Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 5/9] powerpc/64: Retrieve number of L1 cache sets from device-tree Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 6/9] powerpc/64: Clean up ppc64_caches using a struct per cache Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 7/9] powerpc/64: Add L2 and L3 cache shape info Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 8/9] powerpc/64: Hard code cache geometry on POWER8 Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 9/9] powerpc: A new cache geometry aux vectors Benjamin Herrenschmidt
2017-01-10 16:16   ` Paul Clarke
2017-01-10 16:26     ` Benjamin Herrenschmidt
2017-01-30 20:27   ` Michael Ellerman
2017-01-30 20:35     ` Benjamin Herrenschmidt
  -- strict thread matches above, loose matches on Subject: below --
2017-01-04  5:15 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.