Skip to contentSkip to conversation

misc SLB patches

PATCH New Nicholas Piggin 1 participant 4 messages Aug 28, 2018 PowerPC

lore
Share & tools
lore

Nicholas Piggin

author reviewer
#0 lore raw

cover misc SLB patches

These are a few bits and pieces I collected I'll get out of the way ahead of the SLB rewrite in C patch and subsequent improvements.

Nicholas Piggin (3):
powerpc/64s/hash: Fix stab_rr off by one initialization powerpc/64s/hash: Use POWER9 SLBIA IH=3 variant in switch_mm powerpc/64s/hash: avoid the POWER5 < DD2.1 slb invalidate workaround

    on POWER8/9
 arch/powerpc/kernel/entry_64.S |  2 ++
 arch/powerpc/mm/slb.c          | 58 ++++++++++++++++++++++------------
 arch/powerpc/xmon/xmon.c       | 11 ++++---
 3 files changed, 46 insertions(+), 25 deletions(-)
Signature · 1 line
2.18.0
author reviewer
#1 lore raw

PATCH 1/3 powerpc/64s/hash: Fix stab_rr off by one initialization

This causes SLB alloation to start 1 beyond the start of the SLB. There is no real problem because after it wraps it stats behaving properly, it's just surprisig to see when looking at SLB traces.

---
 arch/powerpc/mm/slb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/slb.c +1 -1
index 9f574e59d178..2f162c6e52d4 100644
@@ -355,7 +355,7 @@ void slb_initialize(void)
 #endif
 	}
 
-	get_paca()->stab_rr = SLB_NUM_BOLTED;
+	get_paca()->stab_rr = SLB_NUM_BOLTED - 1;
 
 	lflags = SLB_VSID_KERNEL | linear_llp;
 	vflags = SLB_VSID_KERNEL | vmalloc_llp;
Signature · 1 line
2.18.0
author reviewer
#2 lore raw

PATCH 2/3 powerpc/64s/hash: Use POWER9 SLBIA IH=3 variant in switch_mm

In reply to Nicholas Piggin

POWER9 introduces SLBIA IH=3, which invalidates all SLB entries and associated lookaside information that have a class value of 1, which Linux assigns to user addresses. This matches what switch_slb wants, and allows a simple fast implementation that avoids the slb_cache complexity.

As a side-effect, the POWER5 < DD2.1 SLB invalidation workaround is avoided on POWER9.

Process context switching rate is improved about 2.2% for a small process (that hits the slb cache).

---
 arch/powerpc/mm/slb.c    | 56 ++++++++++++++++++++++++++--------------
 arch/powerpc/xmon/xmon.c | 11 +++++---
 2 files changed, 43 insertions(+), 24 deletions(-)
arch/powerpc/mm/slb.c +36 -20
index 2f162c6e52d4..51afed85cfc3 100644
@@ -238,29 +238,42 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 	 * which would update the slb_cache/slb_cache_ptr fields in the PACA.
 	 */
 	hard_irq_disable();
-	offset = get_paca()->slb_cache_ptr;
-	if (!mmu_has_feature(MMU_FTR_NO_SLBIE_B) &&
-	    offset <= SLB_CACHE_ENTRIES) {
-		int i;
-		asm volatile("isync" : : : "memory");
-		for (i = 0; i < offset; i++) {
-			slbie_data = (unsigned long)get_paca()->slb_cache[i]
-				<< SID_SHIFT; /* EA */
-			slbie_data |= user_segment_size(slbie_data)
-				<< SLBIE_SSIZE_SHIFT;
-			slbie_data |= SLBIE_C; /* C set for user addresses */
-			asm volatile("slbie %0" : : "r" (slbie_data));
-		}
-		asm volatile("isync" : : : "memory");
+
+	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+		/*
+		 * SLBIA IH=3 invalidates all Class=1 SLBEs and their
+		 * associated lookaside structures, which matches what
+		 * switch_slb wants. So ARCH_300 does not use the slb
+		 * cache.
+		 */
+		asm volatile("isync ; " PPC_SLBIA(3)" ; isync");
 	} else {
-		__slb_flush_and_rebolt();
-	}
+		offset = get_paca()->slb_cache_ptr;
+		if (!mmu_has_feature(MMU_FTR_NO_SLBIE_B) &&
+		    offset <= SLB_CACHE_ENTRIES) {
+			int i;
+			asm volatile("isync" : : : "memory");
+			for (i = 0; i < offset; i++) {
+				/* EA */
+				slbie_data = (unsigned long)
+					get_paca()->slb_cache[i] << SID_SHIFT;
+				slbie_data |= user_segment_size(slbie_data)
+						<< SLBIE_SSIZE_SHIFT;
+				slbie_data |= SLBIE_C; /* user slbs have C=1 */
+				asm volatile("slbie %0" : : "r" (slbie_data));
+			}
+			asm volatile("isync" : : : "memory");
+		} else {
+			__slb_flush_and_rebolt();
+		}
 
-	/* Workaround POWER5 < DD2.1 issue */
-	if (offset == 1 || offset > SLB_CACHE_ENTRIES)
-		asm volatile("slbie %0" : : "r" (slbie_data));
+		/* Workaround POWER5 < DD2.1 issue */
+		if (offset == 1 || offset > SLB_CACHE_ENTRIES)
+			asm volatile("slbie %0" : : "r" (slbie_data));
+
+		get_paca()->slb_cache_ptr = 0;
+	}
 
-	get_paca()->slb_cache_ptr = 0;
 	copy_mm_to_paca(mm);
 
 	/*
@@ -388,6 +401,9 @@ static void insert_slb_entry(unsigned long vsid, unsigned long ea,
 	enum slb_index index;
 	int slb_cache_index;
 
+	if (cpu_has_feature(CPU_FTR_ARCH_300))
+		return; /* ISAv3.0B and later does not use slb_cache */
+
 	/*
 	 * We are irq disabled, hence should be safe to access PACA.
 	 */
arch/powerpc/xmon/xmon.c +7 -4
index 379ae7222099..8c1d8b4bf6d5 100644
@@ -2393,10 +2393,13 @@ static void dump_one_paca(int cpu)
 		}
 	}
 	DUMP(p, vmalloc_sllp, "%#-*x");
-	DUMP(p, slb_cache_ptr, "%#-*x");
-	for (i = 0; i < SLB_CACHE_ENTRIES; i++)
-		printf(" %-*s[%d] = 0x%016x\n",
-		       22, "slb_cache", i, p->slb_cache[i]);
+
+	if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
+		DUMP(p, slb_cache_ptr, "%#-*x");
+		for (i = 0; i < SLB_CACHE_ENTRIES; i++)
+			printf(" %-*s[%d] = 0x%016x\n",
+			       22, "slb_cache", i, p->slb_cache[i]);
+	}
 
 	DUMP(p, rfi_flush_fallback_area, "%-*px");
 #endif
Signature · 1 line
2.18.0
author reviewer
#3 lore raw

PATCH 3/3 powerpc/64s/hash: avoid the POWER5 < DD2.1 slb invalidate workaround on POWER8/9

In reply to Nicholas Piggin

I only have POWER8/9 to test, so just remove it for those.

---
 arch/powerpc/kernel/entry_64.S | 2 ++
 1 file changed, 2 insertions(+)
arch/powerpc/kernel/entry_64.S +2 -0
index 2206912ea4f0..77a888bfcb53 100644
@@ -672,7 +672,9 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 
 	isync
 	slbie	r6
+BEGIN_FTR_SECTION
 	slbie	r6		/* Workaround POWER5 < DD2.1 issue */
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 	slbmte	r7,r0
 	isync
 2:
Signature · 1 line
2.18.0