[PATCH] powerpc: thp: Use tlbiel wherever possible

Subsystems: linux for powerpc (32-bit and 64-bit), the rest

STALE4392d

5 messages, 3 authors, 2014-08-07 · open the first message on its own page

[PATCH] powerpc: thp: Use tlbiel wherever possible

From: Aneesh Kumar K.V <hidden>
Date: 2014-08-05 06:48:25

If we know that user address space has never executed on other cpus
we could use tlbiel.

Signed-off-by: Aneesh Kumar K.V <redacted>
---
 arch/powerpc/include/asm/machdep.h    |  2 +-
 arch/powerpc/mm/hash_native_64.c      |  4 ++--
 arch/powerpc/mm/hugepage-hash64.c     | 10 ++++++----
 arch/powerpc/mm/pgtable_64.c          | 11 ++++++++---
 arch/powerpc/platforms/pseries/lpar.c |  2 +-
 5 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 8dcb721d03d8..fe7a11ae9d9c 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -60,7 +60,7 @@ struct machdep_calls {
 	void		(*hugepage_invalidate)(unsigned long vsid,
 					       unsigned long addr,
 					       unsigned char *hpte_slot_array,
-					       int psize, int ssize);
+					       int psize, int ssize, int local);
 	/* special for kexec, to be called in real mode, linear mapping is
 	 * destroyed as well */
 	void		(*hpte_clear_all)(void);
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index afc0a8295f84..88de8a869c98 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -415,7 +415,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
 static void native_hugepage_invalidate(unsigned long vsid,
 				       unsigned long addr,
 				       unsigned char *hpte_slot_array,
-				       int psize, int ssize)
+				       int psize, int ssize, int local)
 {
 	int i;
 	struct hash_pte *hptep;
@@ -461,7 +461,7 @@ static void native_hugepage_invalidate(unsigned long vsid,
 		 * instruction compares entry_VA in tlb with the VA specified
 		 * here
 		 */
-		tlbie(vpn, psize, actual_psize, ssize, 0);
+		tlbie(vpn, psize, actual_psize, ssize, local);
 	}
 	local_irq_restore(flags);
 }
diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c
index 5f5e6328c21c..3e87005cfb79 100644
--- a/arch/powerpc/mm/hugepage-hash64.c
+++ b/arch/powerpc/mm/hugepage-hash64.c
@@ -19,7 +19,8 @@
 #include <asm/machdep.h>
 
 static void invalidate_old_hpte(unsigned long vsid, unsigned long addr,
-				pmd_t *pmdp, unsigned int psize, int ssize)
+				pmd_t *pmdp, unsigned int psize,
+				int ssize, int local)
 {
 	int i, max_hpte_count, valid;
 	unsigned long s_addr;
@@ -38,7 +39,7 @@ static void invalidate_old_hpte(unsigned long vsid, unsigned long addr,
 
 	if (ppc_md.hugepage_invalidate)
 		return ppc_md.hugepage_invalidate(vsid, s_addr, hpte_slot_array,
-						  psize, ssize);
+						  psize, ssize, local);
 	/*
 	 * No bluk hpte removal support, invalidate each entry
 	 */
@@ -64,7 +65,7 @@ static void invalidate_old_hpte(unsigned long vsid, unsigned long addr,
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += hidx & _PTEIDX_GROUP_IX;
 		ppc_md.hpte_invalidate(slot, vpn, psize,
-				       MMU_PAGE_16M, ssize, 0);
+				       MMU_PAGE_16M, ssize, local);
 	}
 }
 
@@ -145,7 +146,8 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
 		 * hash page table entries.
 		 */
 		if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO))
-			invalidate_old_hpte(vsid, ea, pmdp, MMU_PAGE_64K, ssize);
+			invalidate_old_hpte(vsid, ea, pmdp, MMU_PAGE_64K,
+					    ssize, local);
 	}
 
 	valid = hpte_valid(hpte_slot_array, index);
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index ecc4079ca56c..b1ea87b34f79 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -731,10 +731,11 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
 void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
 			    pmd_t *pmdp, unsigned long old_pmd)
 {
-	int ssize, i;
+	int ssize, i, local = 0;
 	unsigned long s_addr;
 	int max_hpte_count;
 	unsigned int psize, valid;
+	const struct cpumask *tmp;
 	unsigned char *hpte_slot_array;
 	unsigned long hidx, vpn, vsid, hash, shift, slot;
 
@@ -770,10 +771,14 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
 		ssize = mmu_kernel_ssize;
 	}
 
+	tmp = cpumask_of(smp_processor_id());
+	if (cpumask_equal(mm_cpumask(mm), tmp))
+		local = 1;
+
 	if (ppc_md.hugepage_invalidate)
 		return ppc_md.hugepage_invalidate(vsid, s_addr,
 						  hpte_slot_array,
-						  psize, ssize);
+						  psize, ssize, local);
 	/*
 	 * No bluk hpte removal support, invalidate each entry
 	 */
@@ -799,7 +804,7 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += hidx & _PTEIDX_GROUP_IX;
 		ppc_md.hpte_invalidate(slot, vpn, psize,
-				       MMU_PAGE_16M, ssize, 0);
+				       MMU_PAGE_16M, ssize, local);
 	}
 }
 
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index ccf6f162f69c..c543c20ffabb 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -433,7 +433,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
 static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
 					     unsigned long addr,
 					     unsigned char *hpte_slot_array,
-					     int psize, int ssize)
+					     int psize, int ssize, int local)
 {
 	int i, index = 0;
 	unsigned long s_addr = addr;
-- 
1.9.1

Re: [PATCH] powerpc: thp: Use tlbiel wherever possible

From: Aneesh Kumar K.V <hidden>
Date: 2014-08-06 14:46:28

"Aneesh Kumar K.V" [off-list ref] writes:
If we know that user address space has never executed on other cpus
we could use tlbiel.

Signed-off-by: Aneesh Kumar K.V <redacted>
Now checking against flush_hash_page, I am wondering whether I need to handle
transcational memory in case of tlbiel ? Michael, can you let me know if
this is needed ?


-aneesh

Re: [PATCH] powerpc: thp: Use tlbiel wherever possible

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2014-08-06 20:30:55

On Wed, 2014-08-06 at 20:16 +0530, Aneesh Kumar K.V wrote:
"Aneesh Kumar K.V" [off-list ref] writes:
quoted
If we know that user address space has never executed on other cpus
we could use tlbiel.

Signed-off-by: Aneesh Kumar K.V <redacted>
Now checking against flush_hash_page, I am wondering whether I need to handle
transcational memory in case of tlbiel ? Michael, can you let me know if
this is needed ?
Also, beware that we have code that sets "tlbiel" in the page definition
array to 0 on all but 4k and 64k pages...

Cheers,
Ben.

Re: [PATCH] powerpc: thp: Use tlbiel wherever possible

From: Michael Neuling <hidden>
Date: 2014-08-06 23:12:17

On Wed, 2014-08-06 at 20:16 +0530, Aneesh Kumar K.V wrote:
"Aneesh Kumar K.V" [off-list ref] writes:
=20
quoted
If we know that user address space has never executed on other cpus
we could use tlbiel.

Signed-off-by: Aneesh Kumar K.V <redacted>
=20
Now checking against flush_hash_page, I am wondering whether I need to ha=
ndle
transcational memory in case of tlbiel ? Michael, can you let me know if
this is needed ?
Yeah, you do need to add something. =20

local tlbie won't abort the transaction (broadcast will abort), so you
need to do a explicit tabort if there is an active transaction, to make
sure the transaction is doomed.

Mikey

Re: [PATCH] powerpc: thp: Use tlbiel wherever possible

From: Aneesh Kumar K.V <hidden>
Date: 2014-08-07 06:05:09

Benjamin Herrenschmidt [off-list ref] writes:
On Wed, 2014-08-06 at 20:16 +0530, Aneesh Kumar K.V wrote:
quoted
"Aneesh Kumar K.V" [off-list ref] writes:
quoted
If we know that user address space has never executed on other cpus
we could use tlbiel.

Signed-off-by: Aneesh Kumar K.V <redacted>
Now checking against flush_hash_page, I am wondering whether I need to handle
transcational memory in case of tlbiel ? Michael, can you let me know if
this is needed ?
Also, beware that we have code that sets "tlbiel" in the page definition
array to 0 on all but 4k and 64k pages...
Ok we use base page size to determine whether we can use tlbiel or not. 

static inline void tlbie(unsigned long vpn, int psize, int apsize,
			 int ssize, int local)
{
....
	if (use_local)
		use_local = mmu_psize_defs[psize].tlbiel;

With that we should be ok, because we are using 4k and 64k base page
size and we have

/*
 * We don't know for sure what's up with tlbiel, so
 * for now we only set it for 4K and 64K pages
 */
if (base_idx == MMU_PAGE_4K || base_idx == MMU_PAGE_64K)
	def->tlbiel = 1;
else
	def->tlbiel = 0;


-aneesh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help