linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI
@ 2020-06-06  4:02 Bibo Mao
  2020-06-06  4:02 ` [PATCH v2 2/2] MIPS: Add writable-applies-readable policy with pgrot Bibo Mao
  2020-07-26  8:32 ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Thomas Bogendoerfer
  0 siblings, 2 replies; 19+ messages in thread
From: Bibo Mao @ 2020-06-06  4:02 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Andrew Morton, Paul Burton, Jiaxun Yang
  Cc: linux-mips, linux-kernel, linux-arch, linux-mm

On MIPS system which has rixi hardware bit, page access bit is not
set in pgrot. For memory reading, there will be one page fault to
allocate physical page; however valid bit is not set, there will
be the second fast tlb-miss fault handling to set valid/access bit.

This patch set page access/valid bit with pgrot if there is reading
access privilege. It will reduce one tlb-miss handling for memory
reading access.

The valid/access bit will be cleared in order to track memory
accessing activity. If the page is accessed, tlb-miss fast handling
will set valid/access bit, pte_sw_mkyoung is not necessary in slow
page fault path. This patch removes pte_sw_mkyoung function which
is defined as empty function except MIPS system.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Acked-by: Andrew Morton <akpm@linux-foundation.org>
---
v2:
- refine commit log title
---
 arch/mips/include/asm/pgtable.h | 10 ++++++++--
 arch/mips/mm/cache.c            | 34 +++++++++++++++++-----------------
 include/asm-generic/pgtable.h   | 16 ----------------
 mm/memory.c                     |  3 ---
 4 files changed, 25 insertions(+), 38 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 85b39c9..d066469 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -25,6 +25,14 @@
 struct mm_struct;
 struct vm_area_struct;
 
+#define __PP	_PAGE_PRESENT
+#define __NX	_PAGE_NO_EXEC
+#define __NR	_PAGE_NO_READ
+#define ___W	_PAGE_WRITE
+#define ___A	_PAGE_ACCESSED
+#define ___R	(_PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __PC	_page_cachable_default
+
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
 				 _page_cachable_default)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
@@ -414,8 +422,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
 	return pte;
 }
 
-#define pte_sw_mkyoung	pte_mkyoung
-
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
 
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index ad6df1c..f814e43 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -158,23 +158,23 @@ void __update_cache(unsigned long address, pte_t pte)
 static inline void setup_protection_map(void)
 {
 	if (cpu_has_rixi) {
-		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-
-		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
-		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
-		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
-		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
+		protection_map[0]  = __pgprot(__PC | __PP | __NX | __NR);
+		protection_map[1]  = __pgprot(__PC | __PP | __NX | ___R);
+		protection_map[2]  = __pgprot(__PC | __PP | __NX | __NR);
+		protection_map[3]  = __pgprot(__PC | __PP | __NX | ___R);
+		protection_map[4]  = __pgprot(__PC | __PP | ___R);
+		protection_map[5]  = __pgprot(__PC | __PP | ___R);
+		protection_map[6]  = __pgprot(__PC | __PP | ___R);
+		protection_map[7]  = __pgprot(__PC | __PP | ___R);
+
+		protection_map[8]  = __pgprot(__PC | __PP | __NX | __NR);
+		protection_map[9]  = __pgprot(__PC | __PP | __NX | ___R);
+		protection_map[10] = __pgprot(__PC | __PP | __NX | ___W | __NR);
+		protection_map[11] = __pgprot(__PC | __PP | __NX | ___W | ___R);
+		protection_map[12] = __pgprot(__PC | __PP | ___R);
+		protection_map[13] = __pgprot(__PC | __PP | ___R);
+		protection_map[14] = __pgprot(__PC | __PP | ___W | ___R);
+		protection_map[15] = __pgprot(__PC | __PP | ___W | ___R);
 
 	} else {
 		protection_map[0] = PAGE_NONE;
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index b5278ec..fa5c73f 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -244,22 +244,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 }
 #endif
 
-/*
- * On some architectures hardware does not set page access bit when accessing
- * memory page, it is responsibilty of software setting this bit. It brings
- * out extra page fault penalty to track page access bit. For optimization page
- * access bit can be set during all page fault flow on these arches.
- * To be differentiate with macro pte_mkyoung, this macro is used on platforms
- * where software maintains page access bit.
- */
-#ifndef pte_sw_mkyoung
-static inline pte_t pte_sw_mkyoung(pte_t pte)
-{
-	return pte;
-}
-#define pte_sw_mkyoung	pte_sw_mkyoung
-#endif
-
 #ifndef pte_savedwrite
 #define pte_savedwrite pte_write
 #endif
diff --git a/mm/memory.c b/mm/memory.c
index c7c8960..8bb31c4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2704,7 +2704,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
-		entry = pte_sw_mkyoung(entry);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 		/*
 		 * Clear the pte entry and flush it first, before updating the
@@ -3379,7 +3378,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 	__SetPageUptodate(page);
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (vma->vm_flags & VM_WRITE)
 		entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3662,7 +3660,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
 
 	flush_icache_page(vma, page);
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (write)
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 	/* copy-on-write page */
-- 
1.8.3.1


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

* [PATCH v2 2/2] MIPS: Add writable-applies-readable policy with pgrot
  2020-06-06  4:02 [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Bibo Mao
@ 2020-06-06  4:02 ` Bibo Mao
  2020-07-26  8:32 ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Thomas Bogendoerfer
  1 sibling, 0 replies; 19+ messages in thread
From: Bibo Mao @ 2020-06-06  4:02 UTC (permalink / raw)
  To: Thomas Bogendoerfer, Andrew Morton, Paul Burton, Jiaxun Yang
  Cc: linux-mips, linux-kernel, linux-arch, linux-mm

On Linux system, writable applies readable privilege in most
architectures, this patch adds this policy on MIPS platform
where hardware rixi is supported.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/mips/mm/cache.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index f814e43..dae0617 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -160,7 +160,7 @@ static inline void setup_protection_map(void)
 	if (cpu_has_rixi) {
 		protection_map[0]  = __pgprot(__PC | __PP | __NX | __NR);
 		protection_map[1]  = __pgprot(__PC | __PP | __NX | ___R);
-		protection_map[2]  = __pgprot(__PC | __PP | __NX | __NR);
+		protection_map[2]  = __pgprot(__PC | __PP | __NX | ___R);
 		protection_map[3]  = __pgprot(__PC | __PP | __NX | ___R);
 		protection_map[4]  = __pgprot(__PC | __PP | ___R);
 		protection_map[5]  = __pgprot(__PC | __PP | ___R);
@@ -169,7 +169,7 @@ static inline void setup_protection_map(void)
 
 		protection_map[8]  = __pgprot(__PC | __PP | __NX | __NR);
 		protection_map[9]  = __pgprot(__PC | __PP | __NX | ___R);
-		protection_map[10] = __pgprot(__PC | __PP | __NX | ___W | __NR);
+		protection_map[10] = __pgprot(__PC | __PP | __NX | ___W | ___R);
 		protection_map[11] = __pgprot(__PC | __PP | __NX | ___W | ___R);
 		protection_map[12] = __pgprot(__PC | __PP | ___R);
 		protection_map[13] = __pgprot(__PC | __PP | ___R);
-- 
1.8.3.1


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

* Re: [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI
  2020-06-06  4:02 [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Bibo Mao
  2020-06-06  4:02 ` [PATCH v2 2/2] MIPS: Add writable-applies-readable policy with pgrot Bibo Mao
@ 2020-07-26  8:32 ` Thomas Bogendoerfer
  2020-08-25  3:20   ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on Huang Pei
  1 sibling, 1 reply; 19+ messages in thread
From: Thomas Bogendoerfer @ 2020-07-26  8:32 UTC (permalink / raw)
  To: Bibo Mao
  Cc: Andrew Morton, Paul Burton, Jiaxun Yang, linux-mips,
	linux-kernel, linux-arch, linux-mm

On Sat, Jun 06, 2020 at 12:02:48PM +0800, Bibo Mao wrote:
> @@ -158,23 +158,23 @@ void __update_cache(unsigned long address, pte_t pte)
>  static inline void setup_protection_map(void)
>  {
>  	if (cpu_has_rixi) {
> -		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> -		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> -		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -
> -		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> -		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
> -		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> -		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
> -		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
> +		protection_map[0]  = __pgprot(__PC | __PP | __NX | __NR);
> +		protection_map[1]  = __pgprot(__PC | __PP | __NX | ___R);
> +		protection_map[2]  = __pgprot(__PC | __PP | __NX | __NR);
> +		protection_map[3]  = __pgprot(__PC | __PP | __NX | ___R);
> +		protection_map[4]  = __pgprot(__PC | __PP | ___R);
> +		protection_map[5]  = __pgprot(__PC | __PP | ___R);
> +		protection_map[6]  = __pgprot(__PC | __PP | ___R);
> +		protection_map[7]  = __pgprot(__PC | __PP | ___R);
> +
> +		protection_map[8]  = __pgprot(__PC | __PP | __NX | __NR);
> +		protection_map[9]  = __pgprot(__PC | __PP | __NX | ___R);
> +		protection_map[10] = __pgprot(__PC | __PP | __NX | ___W | __NR);
> +		protection_map[11] = __pgprot(__PC | __PP | __NX | ___W | ___R);
> +		protection_map[12] = __pgprot(__PC | __PP | ___R);
> +		protection_map[13] = __pgprot(__PC | __PP | ___R);
> +		protection_map[14] = __pgprot(__PC | __PP | ___W | ___R);
> +		protection_map[15] = __pgprot(__PC | __PP | ___W | ___R);

you are doing two steps in one go, so it's not obvious you are not only
using some macros, but also changing semantics. And while there are already
really long lines, please leave it that way and only do the access bit
change.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

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

* Re: [PATCH v2 1/2] MIPS: Set page access bit with pgprot on
  2020-07-26  8:32 ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Thomas Bogendoerfer
@ 2020-08-25  3:20   ` Huang Pei
  2020-08-25  3:20     ` [PATCH] MIPS: make userspace mapping young by default Huang Pei
  0 siblings, 1 reply; 19+ messages in thread
From: Huang Pei @ 2020-08-25  3:20 UTC (permalink / raw)
  To: tsbogend
  Cc: akpm, jiaxun.yang, linux-arch, linux-kernel, linux-mips,
	linux-mm, maobibo, paulburton

adjust the code and add support non-rixi 



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

* [PATCH] MIPS: make userspace mapping young by default
  2020-08-25  3:20   ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on Huang Pei
@ 2020-08-25  3:20     ` Huang Pei
  0 siblings, 0 replies; 19+ messages in thread
From: Huang Pei @ 2020-08-25  3:20 UTC (permalink / raw)
  To: tsbogend
  Cc: akpm, jiaxun.yang, linux-arch, linux-kernel, linux-mips,
	linux-mm, maobibo, paulburton

This patch adds support for non-rixi, based on [1].

MIPS page fault path take 3 exception (1 tlb miss + 2 tlb invalid), but
the second tlb invalid exception is just caused by __update_tlb from
do_page_fault writing tlb without _PAGE_VALID set. With this patch, it
only take 1 tlb miss + 1 tlb invalid exceptions

[1]: https://lkml.kernel.org/lkml/1591416169-26666-1-git-send-email-maobibo@loongson.cn/

Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
 arch/mips/include/asm/pgtable.h | 32 +++++++++++++++-----------------
 arch/mips/mm/cache.c            | 25 +++++++++++++------------
 mm/memory.c                     |  3 ---
 3 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index dd7a0f552cac..aaafe3d6a0a1 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -25,22 +25,22 @@
 struct mm_struct;
 struct vm_area_struct;
 
-#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
-				 _page_cachable_default)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
-				 _page_cachable_default)
-#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
-				 _page_cachable_default)
-#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | \
-				 _page_cachable_default)
-#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-				 _PAGE_GLOBAL | _page_cachable_default)
-#define PAGE_KERNEL_NC	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-				 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
-				 _page_cachable_default)
+#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
+                                _page_cachable_default)
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
+                                __READABLE | _page_cachable_default)
+#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
+                                __READABLE | _page_cachable_default)
+#define PAGE_READONLY  __pgprot(_PAGE_PRESENT |  __READABLE | \
+                                _page_cachable_default)
+#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+                                _PAGE_GLOBAL | _page_cachable_default)
+#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+                                _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
+                                _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
-			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
+                       __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
 /*
  * If _PAGE_NO_EXEC is not defined, we can't do page protection for
@@ -414,8 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
 	return pte;
 }
 
-#define pte_sw_mkyoung	pte_mkyoung
-
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
 
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 3e81ba000096..ed75f2871aad 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -159,22 +159,23 @@ static inline void setup_protection_map(void)
 {
 	if (cpu_has_rixi) {
 		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
 		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
 
 		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
 		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
-		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
-		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
-		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
+		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | __READABLE);
+		protection_map[12]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[13]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[14]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+		protection_map[15]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+
 
 	} else {
 		protection_map[0] = PAGE_NONE;
diff --git a/mm/memory.c b/mm/memory.c
index 602f4283122f..5100ab5bcf77 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2705,7 +2705,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
-		entry = pte_sw_mkyoung(entry);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 		/*
 		 * Clear the pte entry and flush it first, before updating the
@@ -3386,7 +3385,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 	__SetPageUptodate(page);
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (vma->vm_flags & VM_WRITE)
 		entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3661,7 +3659,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
 
 	flush_icache_page(vma, page);
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (write)
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 	/* copy-on-write page */
-- 
2.17.1


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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-08 17:44     ` Christophe Leroy
@ 2021-02-08 19:48       ` Andrew Morton
  0 siblings, 0 replies; 19+ messages in thread
From: Andrew Morton @ 2021-02-08 19:48 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Thomas Bogendoerfer, Huang Pei, ambrosehua, Bibo Mao, linux-mips,
	linux-arch, linux-mm, Jiaxun Yang, Paul Burton, Li Xuefeng,
	Yang Tiezhu, Gao Juxin, Fuxin Zhang, Huacai Chen,
	Nicholas Piggin

On Mon, 8 Feb 2021 18:44:22 +0100 Christophe Leroy <christophe.leroy@csgroup.eu> wrote:

> 
> 
> Le 06/02/2021 à 00:41, Andrew Morton a écrit :
> > On Thu, 4 Feb 2021 16:22:39 +0100 Thomas Bogendoerfer <tsbogend@alpha.franken.de> wrote:
> > 
> >> On Thu, Feb 04, 2021 at 09:39:42AM +0800, Huang Pei wrote:
> >>> MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
> >>> + 2 TLB Invalid), butthe second TLB Invalid exception is just
> >>> triggered by __update_tlb from do_page_fault writing tlb without
> >>> _PAGE_VALID set. With this patch, user space mapping prot is made
> >>> young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
> >>> and it only take 1 TLB Miss + 1 TLB Invalid exception
> >>>
> >>> Remove pte_sw_mkyoung without polluting MM code and make page fault
> >>> delay of MIPS on par with other architecture
> >>>
> >>> Signed-off-by: Huang Pei <huangpei@loongson.cn>
> >>> ---
> >>>   arch/mips/mm/cache.c    | 30 ++++++++++++++++--------------
> >>>   include/linux/pgtable.h |  8 --------
> >>>   mm/memory.c             |  3 ---
> >>>   3 files changed, 16 insertions(+), 25 deletions(-)
> >>
> >> Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> >>
> >> Andrew, can you take this patch through your tree ?
> > 
> > Sure.  I'll drop Christophe's "mm/memory.c: remove pte_sw_mkyoung()"
> > (https://lkml.kernel.org/r/f302ef92c48d1f08a0459aaee1c568ca11213814.1612345700.git.christophe.leroy@csgroup.eu)
> > in favour of this one.
> > 
> 
> Pitty. My patch was improving page faults on powerpc/32.

How does it do that?  By running pte_mkyoung() for powerpc32?  Such a
change is still valid, isn't it?

> That one is only addressing MIPS.

It cleans up core code nicely, by removing a MIPS wart.  We can still
add a ppc32 wart?

> 
> Any plan to take the series from Nick 
> https://patchwork.kernel.org/project/linux-mm/list/?series=404539 ?

I expect so.  After -rc1, if the churn is settling down and reviewers
are happy enough.

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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-05 23:41   ` Andrew Morton
@ 2021-02-08 17:44     ` Christophe Leroy
  2021-02-08 19:48       ` Andrew Morton
  0 siblings, 1 reply; 19+ messages in thread
From: Christophe Leroy @ 2021-02-08 17:44 UTC (permalink / raw)
  To: Andrew Morton, Thomas Bogendoerfer
  Cc: Huang Pei, ambrosehua, Bibo Mao, linux-mips, linux-arch,
	linux-mm, Jiaxun Yang, Paul Burton, Li Xuefeng, Yang Tiezhu,
	Gao Juxin, Fuxin Zhang, Huacai Chen, Nicholas Piggin



Le 06/02/2021 à 00:41, Andrew Morton a écrit :
> On Thu, 4 Feb 2021 16:22:39 +0100 Thomas Bogendoerfer <tsbogend@alpha.franken.de> wrote:
> 
>> On Thu, Feb 04, 2021 at 09:39:42AM +0800, Huang Pei wrote:
>>> MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
>>> + 2 TLB Invalid), butthe second TLB Invalid exception is just
>>> triggered by __update_tlb from do_page_fault writing tlb without
>>> _PAGE_VALID set. With this patch, user space mapping prot is made
>>> young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
>>> and it only take 1 TLB Miss + 1 TLB Invalid exception
>>>
>>> Remove pte_sw_mkyoung without polluting MM code and make page fault
>>> delay of MIPS on par with other architecture
>>>
>>> Signed-off-by: Huang Pei <huangpei@loongson.cn>
>>> ---
>>>   arch/mips/mm/cache.c    | 30 ++++++++++++++++--------------
>>>   include/linux/pgtable.h |  8 --------
>>>   mm/memory.c             |  3 ---
>>>   3 files changed, 16 insertions(+), 25 deletions(-)
>>
>> Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
>>
>> Andrew, can you take this patch through your tree ?
> 
> Sure.  I'll drop Christophe's "mm/memory.c: remove pte_sw_mkyoung()"
> (https://lkml.kernel.org/r/f302ef92c48d1f08a0459aaee1c568ca11213814.1612345700.git.christophe.leroy@csgroup.eu)
> in favour of this one.
> 

Pitty. My patch was improving page faults on powerpc/32. That one is only addressing MIPS.

Any plan to take the series from Nick 
https://patchwork.kernel.org/project/linux-mm/list/?series=404539 ?

Christophe

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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-04 15:22 ` Thomas Bogendoerfer
@ 2021-02-05 23:41   ` Andrew Morton
  2021-02-08 17:44     ` Christophe Leroy
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Morton @ 2021-02-05 23:41 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Huang Pei, ambrosehua, Bibo Mao, linux-mips, linux-arch,
	linux-mm, Jiaxun Yang, Paul Burton, Li Xuefeng, Yang Tiezhu,
	Gao Juxin, Fuxin Zhang, Huacai Chen, Christophe Leroy

On Thu, 4 Feb 2021 16:22:39 +0100 Thomas Bogendoerfer <tsbogend@alpha.franken.de> wrote:

> On Thu, Feb 04, 2021 at 09:39:42AM +0800, Huang Pei wrote:
> > MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
> > + 2 TLB Invalid), butthe second TLB Invalid exception is just
> > triggered by __update_tlb from do_page_fault writing tlb without
> > _PAGE_VALID set. With this patch, user space mapping prot is made
> > young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
> > and it only take 1 TLB Miss + 1 TLB Invalid exception
> > 
> > Remove pte_sw_mkyoung without polluting MM code and make page fault
> > delay of MIPS on par with other architecture
> > 
> > Signed-off-by: Huang Pei <huangpei@loongson.cn>
> > ---
> >  arch/mips/mm/cache.c    | 30 ++++++++++++++++--------------
> >  include/linux/pgtable.h |  8 --------
> >  mm/memory.c             |  3 ---
> >  3 files changed, 16 insertions(+), 25 deletions(-)
> 
> Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> 
> Andrew, can you take this patch through your tree ?

Sure.  I'll drop Christophe's "mm/memory.c: remove pte_sw_mkyoung()"
(https://lkml.kernel.org/r/f302ef92c48d1f08a0459aaee1c568ca11213814.1612345700.git.christophe.leroy@csgroup.eu)
in favour of this one.

I changed this patch a bit due to other changes in -next.  Please check
do_set_pte().



From: Huang Pei <huangpei@loongson.cn>
Subject: MIPS: make userspace mapping young by default

MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss + 2
TLB Invalid), butthe second TLB Invalid exception is just triggered by
__update_tlb from do_page_fault writing tlb without _PAGE_VALID set.  With
this patch, user space mapping prot is made young by default (with both
_PAGE_VALID and _PAGE_YOUNG set), and it only take 1 TLB Miss + 1 TLB
Invalid exception

Remove pte_sw_mkyoung without polluting MM code and make page fault delay
of MIPS on par with other architecture

Link: https://lkml.kernel.org/r/20210204013942.8398-1-huangpei@loongson.cn
Signed-off-by: Huang Pei <huangpei@loongson.cn>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Acked-by: <huangpei@loongson.cn>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: <ambrosehua@gmail.com>
Cc: Bibo Mao <maobibo@loongson.cn>
Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Li Xuefeng <lixuefeng@loongson.cn>
Cc: Yang Tiezhu <yangtiezhu@loongson.cn>
Cc: Gao Juxin <gaojuxin@loongson.cn>
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 arch/mips/mm/cache.c    |   30 ++++++++++++++++--------------
 include/linux/pgtable.h |    8 --------
 mm/memory.c             |    4 ----
 3 files changed, 16 insertions(+), 26 deletions(-)

--- a/arch/mips/mm/cache.c~mips-make-userspace-mapping-young-by-default
+++ a/arch/mips/mm/cache.c
@@ -157,29 +157,31 @@ unsigned long _page_cachable_default;
 EXPORT_SYMBOL(_page_cachable_default);
 
 #define PM(p)	__pgprot(_page_cachable_default | (p))
+#define PVA(p)	PM(_PAGE_VALID | _PAGE_ACCESSED | (p))
 
 static inline void setup_protection_map(void)
 {
 	protection_map[0]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-	protection_map[1]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
-	protection_map[2]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-	protection_map[3]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
-	protection_map[4]  = PM(_PAGE_PRESENT);
-	protection_map[5]  = PM(_PAGE_PRESENT);
-	protection_map[6]  = PM(_PAGE_PRESENT);
-	protection_map[7]  = PM(_PAGE_PRESENT);
+	protection_map[1]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
+	protection_map[2]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+	protection_map[3]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
+	protection_map[4]  = PVA(_PAGE_PRESENT);
+	protection_map[5]  = PVA(_PAGE_PRESENT);
+	protection_map[6]  = PVA(_PAGE_PRESENT);
+	protection_map[7]  = PVA(_PAGE_PRESENT);
 
 	protection_map[8]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-	protection_map[9]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
-	protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
+	protection_map[9]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
+	protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
 				_PAGE_NO_READ);
-	protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
-	protection_map[12] = PM(_PAGE_PRESENT);
-	protection_map[13] = PM(_PAGE_PRESENT);
-	protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE);
-	protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE);
+	protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
+	protection_map[12] = PVA(_PAGE_PRESENT);
+	protection_map[13] = PVA(_PAGE_PRESENT);
+	protection_map[14] = PVA(_PAGE_PRESENT);
+	protection_map[15] = PVA(_PAGE_PRESENT);
 }
 
+#undef _PVA
 #undef PM
 
 void cpu_cache_init(void)
--- a/include/linux/pgtable.h~mips-make-userspace-mapping-young-by-default
+++ a/include/linux/pgtable.h
@@ -432,14 +432,6 @@ static inline void ptep_set_wrprotect(st
  * To be differentiate with macro pte_mkyoung, this macro is used on platforms
  * where software maintains page access bit.
  */
-#ifndef pte_sw_mkyoung
-static inline pte_t pte_sw_mkyoung(pte_t pte)
-{
-	return pte;
-}
-#define pte_sw_mkyoung	pte_sw_mkyoung
-#endif
-
 #ifndef pte_savedwrite
 #define pte_savedwrite pte_write
 #endif
--- a/mm/memory.c~mips-make-userspace-mapping-young-by-default
+++ a/mm/memory.c
@@ -2902,7 +2902,6 @@ static vm_fault_t wp_page_copy(struct vm
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
-		entry = pte_sw_mkyoung(entry);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 
 		/*
@@ -3560,7 +3559,6 @@ static vm_fault_t do_anonymous_page(stru
 	__SetPageUptodate(page);
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (vma->vm_flags & VM_WRITE)
 		entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3745,8 +3743,6 @@ void do_set_pte(struct vm_fault *vmf, st
 
 	if (prefault && arch_wants_old_prefaulted_pte())
 		entry = pte_mkold(entry);
-	else
-		entry = pte_sw_mkyoung(entry);
 
 	if (write)
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
_


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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-04  1:39 Huang Pei
  2021-02-04  3:29 ` Nicholas Piggin
@ 2021-02-04 15:22 ` Thomas Bogendoerfer
  2021-02-05 23:41   ` Andrew Morton
  1 sibling, 1 reply; 19+ messages in thread
From: Thomas Bogendoerfer @ 2021-02-04 15:22 UTC (permalink / raw)
  To: Huang Pei, Andrew Morton
  Cc: ambrosehua, Bibo Mao, linux-mips, linux-arch, linux-mm,
	Jiaxun Yang, Paul Burton, Li Xuefeng, Yang Tiezhu, Gao Juxin,
	Fuxin Zhang, Huacai Chen

On Thu, Feb 04, 2021 at 09:39:42AM +0800, Huang Pei wrote:
> MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
> + 2 TLB Invalid), butthe second TLB Invalid exception is just
> triggered by __update_tlb from do_page_fault writing tlb without
> _PAGE_VALID set. With this patch, user space mapping prot is made
> young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
> and it only take 1 TLB Miss + 1 TLB Invalid exception
> 
> Remove pte_sw_mkyoung without polluting MM code and make page fault
> delay of MIPS on par with other architecture
> 
> Signed-off-by: Huang Pei <huangpei@loongson.cn>
> ---
>  arch/mips/mm/cache.c    | 30 ++++++++++++++++--------------
>  include/linux/pgtable.h |  8 --------
>  mm/memory.c             |  3 ---
>  3 files changed, 16 insertions(+), 25 deletions(-)

Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

Andrew, can you take this patch through your tree ?

Thomas.

> 
> diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
> index 23b16bfd97b2..e19cf424bb39 100644
> --- a/arch/mips/mm/cache.c
> +++ b/arch/mips/mm/cache.c
> @@ -156,29 +156,31 @@ unsigned long _page_cachable_default;
>  EXPORT_SYMBOL(_page_cachable_default);
>  
>  #define PM(p)	__pgprot(_page_cachable_default | (p))
> +#define PVA(p)	PM(_PAGE_VALID | _PAGE_ACCESSED | (p))
>  
>  static inline void setup_protection_map(void)
>  {
>  	protection_map[0]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[1]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[2]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[3]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[4]  = PM(_PAGE_PRESENT);
> -	protection_map[5]  = PM(_PAGE_PRESENT);
> -	protection_map[6]  = PM(_PAGE_PRESENT);
> -	protection_map[7]  = PM(_PAGE_PRESENT);
> +	protection_map[1]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[2]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> +	protection_map[3]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[4]  = PVA(_PAGE_PRESENT);
> +	protection_map[5]  = PVA(_PAGE_PRESENT);
> +	protection_map[6]  = PVA(_PAGE_PRESENT);
> +	protection_map[7]  = PVA(_PAGE_PRESENT);
>  
>  	protection_map[8]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[9]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
> +	protection_map[9]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
>  				_PAGE_NO_READ);
> -	protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> -	protection_map[12] = PM(_PAGE_PRESENT);
> -	protection_map[13] = PM(_PAGE_PRESENT);
> -	protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE);
> -	protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE);
> +	protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> +	protection_map[12] = PVA(_PAGE_PRESENT);
> +	protection_map[13] = PVA(_PAGE_PRESENT);
> +	protection_map[14] = PVA(_PAGE_PRESENT);
> +	protection_map[15] = PVA(_PAGE_PRESENT);
>  }
>  
> +#undef _PVA
>  #undef PM
>  
>  void cpu_cache_init(void)
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 8fcdfa52eb4b..8c042627399a 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -432,14 +432,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
>   * To be differentiate with macro pte_mkyoung, this macro is used on platforms
>   * where software maintains page access bit.
>   */
> -#ifndef pte_sw_mkyoung
> -static inline pte_t pte_sw_mkyoung(pte_t pte)
> -{
> -	return pte;
> -}
> -#define pte_sw_mkyoung	pte_sw_mkyoung
> -#endif
> -
>  #ifndef pte_savedwrite
>  #define pte_savedwrite pte_write
>  #endif
> diff --git a/mm/memory.c b/mm/memory.c
> index feff48e1465a..95718a623884 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2890,7 +2890,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
>  		}
>  		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
>  		entry = mk_pte(new_page, vma->vm_page_prot);
> -		entry = pte_sw_mkyoung(entry);
>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>  
>  		/*
> @@ -3548,7 +3547,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
>  	__SetPageUptodate(page);
>  
>  	entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
>  	if (vma->vm_flags & VM_WRITE)
>  		entry = pte_mkwrite(pte_mkdirty(entry));
>  
> @@ -3824,7 +3822,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
>  
>  	flush_icache_page(vma, page);
>  	entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
>  	if (write)
>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>  	/* copy-on-write page */
> -- 
> 2.17.1

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-04 10:34   ` Thomas Bogendoerfer
@ 2021-02-04 11:27     ` Nicholas Piggin
  0 siblings, 0 replies; 19+ messages in thread
From: Nicholas Piggin @ 2021-02-04 11:27 UTC (permalink / raw)
  To: Thomas Bogendoerfer
  Cc: Andrew Morton, ambrosehua, Huacai Chen, Gao Juxin, Huang Pei,
	Jiaxun Yang, linux-arch, linux-mips, linux-mm, Li Xuefeng,
	Bibo Mao, Paul Burton, Yang Tiezhu, Fuxin Zhang

Excerpts from Thomas Bogendoerfer's message of February 4, 2021 8:34 pm:
> On Thu, Feb 04, 2021 at 01:29:26PM +1000, Nicholas Piggin wrote:
>> Excerpts from Huang Pei's message of February 4, 2021 11:39 am:
>> > MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
>> > + 2 TLB Invalid), butthe second TLB Invalid exception is just
>> > triggered by __update_tlb from do_page_fault writing tlb without
>> > _PAGE_VALID set. With this patch, user space mapping prot is made
>> > young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
>> > and it only take 1 TLB Miss + 1 TLB Invalid exception
>> > 
>> > Remove pte_sw_mkyoung without polluting MM code and make page fault
>> > delay of MIPS on par with other architecture
>> > 
>> > Signed-off-by: Huang Pei <huangpei@loongson.cn>
>> 
>> Could we merge this? For the core code,
> 
> sure, but IMHO I should only merge the MIPS part, correct ?

You could ack it for MIPS and Andrew could take it through his tree 
would avoid dependencies.

Thanks,
Nick

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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-04  3:29 ` Nicholas Piggin
  2021-02-04  4:46   ` 黄沛
@ 2021-02-04 10:34   ` Thomas Bogendoerfer
  2021-02-04 11:27     ` Nicholas Piggin
  1 sibling, 1 reply; 19+ messages in thread
From: Thomas Bogendoerfer @ 2021-02-04 10:34 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: ambrosehua, Huang Pei, Andrew Morton, Huacai Chen, Gao Juxin,
	Jiaxun Yang, linux-arch, linux-mips, linux-mm, Li Xuefeng,
	Bibo Mao, Paul Burton, Yang Tiezhu, Fuxin Zhang

On Thu, Feb 04, 2021 at 01:29:26PM +1000, Nicholas Piggin wrote:
> Excerpts from Huang Pei's message of February 4, 2021 11:39 am:
> > MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
> > + 2 TLB Invalid), butthe second TLB Invalid exception is just
> > triggered by __update_tlb from do_page_fault writing tlb without
> > _PAGE_VALID set. With this patch, user space mapping prot is made
> > young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
> > and it only take 1 TLB Miss + 1 TLB Invalid exception
> > 
> > Remove pte_sw_mkyoung without polluting MM code and make page fault
> > delay of MIPS on par with other architecture
> > 
> > Signed-off-by: Huang Pei <huangpei@loongson.cn>
> 
> Could we merge this? For the core code,

sure, but IMHO I should only merge the MIPS part, correct ?

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-04  3:29 ` Nicholas Piggin
@ 2021-02-04  4:46   ` 黄沛
  2021-02-04 10:34   ` Thomas Bogendoerfer
  1 sibling, 0 replies; 19+ messages in thread
From: 黄沛 @ 2021-02-04  4:46 UTC (permalink / raw)
  To: Nicholas Piggin, ambrosehua, Thomas Bogendoerfer
  Cc: Andrew Morton, Huacai Chen, Gao Juxin, Jiaxun Yang, linux-arch,
	linux-mips, linux-mm, Li Xuefeng, Bibo Mao, Paul Burton,
	Yang Tiezhu, Fuxin Zhang

‎I am ok with it


  Original Message  
From: Nicholas Piggin
Sent: 2021年2月4日星期四 11:55
To: ambrosehua@gmail.com; Huang Pei; Thomas Bogendoerfer
Cc: Andrew Morton; Huacai Chen; Gao Juxin; Jiaxun Yang; linux-arch@vger.kernel.org; linux-mips@vger.kernel.org; linux-mm@kvack.org; Li Xuefeng; Bibo Mao; Paul Burton; Yang Tiezhu; Fuxin Zhang
Subject: Re: [PATCH] MIPS: make userspace mapping young by default

Excerpts from Huang Pei's message of February 4, 2021 11:39 am:
> MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
> + 2 TLB Invalid), butthe second TLB Invalid exception is just
> triggered by __update_tlb from do_page_fault writing tlb without
> _PAGE_VALID set. With this patch, user space mapping prot is made
> young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
> and it only take 1 TLB Miss + 1 TLB Invalid exception
> 
> Remove pte_sw_mkyoung without polluting MM code and make page fault
> delay of MIPS on par with other architecture
> 
> Signed-off-by: Huang Pei <huangpei@loongson.cn>

Could we merge this? For the core code,

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> ---
> arch/mips/mm/cache.c | 30 ++++++++++++++++--------------
> include/linux/pgtable.h | 8 --------
> mm/memory.c | 3 ---
> 3 files changed, 16 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
> index 23b16bfd97b2..e19cf424bb39 100644
> --- a/arch/mips/mm/cache.c
> +++ b/arch/mips/mm/cache.c
> @@ -156,29 +156,31 @@ unsigned long _page_cachable_default;
> EXPORT_SYMBOL(_page_cachable_default);
> 
> #define PM(p)	__pgprot(_page_cachable_default | (p))
> +#define PVA(p)	PM(_PAGE_VALID | _PAGE_ACCESSED | (p))
> 
> static inline void setup_protection_map(void)
> {
> protection_map[0] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[1] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[2] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[3] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[4] = PM(_PAGE_PRESENT);
> -	protection_map[5] = PM(_PAGE_PRESENT);
> -	protection_map[6] = PM(_PAGE_PRESENT);
> -	protection_map[7] = PM(_PAGE_PRESENT);
> +	protection_map[1] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[2] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> +	protection_map[3] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[4] = PVA(_PAGE_PRESENT);
> +	protection_map[5] = PVA(_PAGE_PRESENT);
> +	protection_map[6] = PVA(_PAGE_PRESENT);
> +	protection_map[7] = PVA(_PAGE_PRESENT);
> 
> protection_map[8] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[9] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
> +	protection_map[9] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
> _PAGE_NO_READ);
> -	protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> -	protection_map[12] = PM(_PAGE_PRESENT);
> -	protection_map[13] = PM(_PAGE_PRESENT);
> -	protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE);
> -	protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE);
> +	protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> +	protection_map[12] = PVA(_PAGE_PRESENT);
> +	protection_map[13] = PVA(_PAGE_PRESENT);
> +	protection_map[14] = PVA(_PAGE_PRESENT);
> +	protection_map[15] = PVA(_PAGE_PRESENT);
> }
> 
> +#undef _PVA
> #undef PM
> 
> void cpu_cache_init(void)
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 8fcdfa52eb4b..8c042627399a 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -432,14 +432,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
> * To be differentiate with macro pte_mkyoung, this macro is used on platforms
> * where software maintains page access bit.
> */
> -#ifndef pte_sw_mkyoung
> -static inline pte_t pte_sw_mkyoung(pte_t pte)
> -{
> -	return pte;
> -}
> -#define pte_sw_mkyoung	pte_sw_mkyoung
> -#endif
> -
> #ifndef pte_savedwrite
> #define pte_savedwrite pte_write
> #endif
> diff --git a/mm/memory.c b/mm/memory.c
> index feff48e1465a..95718a623884 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2890,7 +2890,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
> }
> flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
> entry = mk_pte(new_page, vma->vm_page_prot);
> -	 entry = pte_sw_mkyoung(entry);
> entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> 
> /*
> @@ -3548,7 +3547,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
> __SetPageUptodate(page);
> 
> entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
> if (vma->vm_flags & VM_WRITE)
> entry = pte_mkwrite(pte_mkdirty(entry));
> 
> @@ -3824,7 +3822,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
> 
> flush_icache_page(vma, page);
> entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
> if (write)
> entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> /* copy-on-write page */
> -- 
> 2.17.1
> 
> 
> 


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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2021-02-04  1:39 Huang Pei
@ 2021-02-04  3:29 ` Nicholas Piggin
  2021-02-04  4:46   ` 黄沛
  2021-02-04 10:34   ` Thomas Bogendoerfer
  2021-02-04 15:22 ` Thomas Bogendoerfer
  1 sibling, 2 replies; 19+ messages in thread
From: Nicholas Piggin @ 2021-02-04  3:29 UTC (permalink / raw)
  To: ambrosehua, Huang Pei, Thomas Bogendoerfer
  Cc: Andrew Morton, Huacai Chen, Gao Juxin, Jiaxun Yang, linux-arch,
	linux-mips, linux-mm, Li Xuefeng, Bibo Mao, Paul Burton,
	Yang Tiezhu, Fuxin Zhang

Excerpts from Huang Pei's message of February 4, 2021 11:39 am:
> MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
> + 2 TLB Invalid), butthe second TLB Invalid exception is just
> triggered by __update_tlb from do_page_fault writing tlb without
> _PAGE_VALID set. With this patch, user space mapping prot is made
> young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
> and it only take 1 TLB Miss + 1 TLB Invalid exception
> 
> Remove pte_sw_mkyoung without polluting MM code and make page fault
> delay of MIPS on par with other architecture
> 
> Signed-off-by: Huang Pei <huangpei@loongson.cn>

Could we merge this? For the core code,

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> ---
>  arch/mips/mm/cache.c    | 30 ++++++++++++++++--------------
>  include/linux/pgtable.h |  8 --------
>  mm/memory.c             |  3 ---
>  3 files changed, 16 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
> index 23b16bfd97b2..e19cf424bb39 100644
> --- a/arch/mips/mm/cache.c
> +++ b/arch/mips/mm/cache.c
> @@ -156,29 +156,31 @@ unsigned long _page_cachable_default;
>  EXPORT_SYMBOL(_page_cachable_default);
>  
>  #define PM(p)	__pgprot(_page_cachable_default | (p))
> +#define PVA(p)	PM(_PAGE_VALID | _PAGE_ACCESSED | (p))
>  
>  static inline void setup_protection_map(void)
>  {
>  	protection_map[0]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[1]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[2]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[3]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[4]  = PM(_PAGE_PRESENT);
> -	protection_map[5]  = PM(_PAGE_PRESENT);
> -	protection_map[6]  = PM(_PAGE_PRESENT);
> -	protection_map[7]  = PM(_PAGE_PRESENT);
> +	protection_map[1]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[2]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> +	protection_map[3]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[4]  = PVA(_PAGE_PRESENT);
> +	protection_map[5]  = PVA(_PAGE_PRESENT);
> +	protection_map[6]  = PVA(_PAGE_PRESENT);
> +	protection_map[7]  = PVA(_PAGE_PRESENT);
>  
>  	protection_map[8]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -	protection_map[9]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
> -	protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
> +	protection_map[9]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
> +	protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
>  				_PAGE_NO_READ);
> -	protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> -	protection_map[12] = PM(_PAGE_PRESENT);
> -	protection_map[13] = PM(_PAGE_PRESENT);
> -	protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE);
> -	protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE);
> +	protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> +	protection_map[12] = PVA(_PAGE_PRESENT);
> +	protection_map[13] = PVA(_PAGE_PRESENT);
> +	protection_map[14] = PVA(_PAGE_PRESENT);
> +	protection_map[15] = PVA(_PAGE_PRESENT);
>  }
>  
> +#undef _PVA
>  #undef PM
>  
>  void cpu_cache_init(void)
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 8fcdfa52eb4b..8c042627399a 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -432,14 +432,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
>   * To be differentiate with macro pte_mkyoung, this macro is used on platforms
>   * where software maintains page access bit.
>   */
> -#ifndef pte_sw_mkyoung
> -static inline pte_t pte_sw_mkyoung(pte_t pte)
> -{
> -	return pte;
> -}
> -#define pte_sw_mkyoung	pte_sw_mkyoung
> -#endif
> -
>  #ifndef pte_savedwrite
>  #define pte_savedwrite pte_write
>  #endif
> diff --git a/mm/memory.c b/mm/memory.c
> index feff48e1465a..95718a623884 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2890,7 +2890,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
>  		}
>  		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
>  		entry = mk_pte(new_page, vma->vm_page_prot);
> -		entry = pte_sw_mkyoung(entry);
>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>  
>  		/*
> @@ -3548,7 +3547,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
>  	__SetPageUptodate(page);
>  
>  	entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
>  	if (vma->vm_flags & VM_WRITE)
>  		entry = pte_mkwrite(pte_mkdirty(entry));
>  
> @@ -3824,7 +3822,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
>  
>  	flush_icache_page(vma, page);
>  	entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
>  	if (write)
>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>  	/* copy-on-write page */
> -- 
> 2.17.1
> 
> 
> 

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

* [PATCH] MIPS: make userspace mapping young by default
@ 2021-02-04  1:39 Huang Pei
  2021-02-04  3:29 ` Nicholas Piggin
  2021-02-04 15:22 ` Thomas Bogendoerfer
  0 siblings, 2 replies; 19+ messages in thread
From: Huang Pei @ 2021-02-04  1:39 UTC (permalink / raw)
  To: Thomas Bogendoerfer, ambrosehua
  Cc: Bibo Mao, Andrew Morton, linux-mips, linux-arch, linux-mm,
	Jiaxun Yang, Paul Burton, Li Xuefeng, Yang Tiezhu, Gao Juxin,
	Fuxin Zhang, Huacai Chen

MIPS page fault path(except huge page) takes 3 exceptions (1 TLB Miss
+ 2 TLB Invalid), butthe second TLB Invalid exception is just
triggered by __update_tlb from do_page_fault writing tlb without
_PAGE_VALID set. With this patch, user space mapping prot is made
young by default (with both _PAGE_VALID and _PAGE_YOUNG set),
and it only take 1 TLB Miss + 1 TLB Invalid exception

Remove pte_sw_mkyoung without polluting MM code and make page fault
delay of MIPS on par with other architecture

Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
 arch/mips/mm/cache.c    | 30 ++++++++++++++++--------------
 include/linux/pgtable.h |  8 --------
 mm/memory.c             |  3 ---
 3 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 23b16bfd97b2..e19cf424bb39 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -156,29 +156,31 @@ unsigned long _page_cachable_default;
 EXPORT_SYMBOL(_page_cachable_default);
 
 #define PM(p)	__pgprot(_page_cachable_default | (p))
+#define PVA(p)	PM(_PAGE_VALID | _PAGE_ACCESSED | (p))
 
 static inline void setup_protection_map(void)
 {
 	protection_map[0]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-	protection_map[1]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
-	protection_map[2]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-	protection_map[3]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
-	protection_map[4]  = PM(_PAGE_PRESENT);
-	protection_map[5]  = PM(_PAGE_PRESENT);
-	protection_map[6]  = PM(_PAGE_PRESENT);
-	protection_map[7]  = PM(_PAGE_PRESENT);
+	protection_map[1]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
+	protection_map[2]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+	protection_map[3]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
+	protection_map[4]  = PVA(_PAGE_PRESENT);
+	protection_map[5]  = PVA(_PAGE_PRESENT);
+	protection_map[6]  = PVA(_PAGE_PRESENT);
+	protection_map[7]  = PVA(_PAGE_PRESENT);
 
 	protection_map[8]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-	protection_map[9]  = PM(_PAGE_PRESENT | _PAGE_NO_EXEC);
-	protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
+	protection_map[9]  = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC);
+	protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE |
 				_PAGE_NO_READ);
-	protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
-	protection_map[12] = PM(_PAGE_PRESENT);
-	protection_map[13] = PM(_PAGE_PRESENT);
-	protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE);
-	protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE);
+	protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
+	protection_map[12] = PVA(_PAGE_PRESENT);
+	protection_map[13] = PVA(_PAGE_PRESENT);
+	protection_map[14] = PVA(_PAGE_PRESENT);
+	protection_map[15] = PVA(_PAGE_PRESENT);
 }
 
+#undef _PVA
 #undef PM
 
 void cpu_cache_init(void)
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 8fcdfa52eb4b..8c042627399a 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -432,14 +432,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
  * To be differentiate with macro pte_mkyoung, this macro is used on platforms
  * where software maintains page access bit.
  */
-#ifndef pte_sw_mkyoung
-static inline pte_t pte_sw_mkyoung(pte_t pte)
-{
-	return pte;
-}
-#define pte_sw_mkyoung	pte_sw_mkyoung
-#endif
-
 #ifndef pte_savedwrite
 #define pte_savedwrite pte_write
 #endif
diff --git a/mm/memory.c b/mm/memory.c
index feff48e1465a..95718a623884 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2890,7 +2890,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
-		entry = pte_sw_mkyoung(entry);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 
 		/*
@@ -3548,7 +3547,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 	__SetPageUptodate(page);
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (vma->vm_flags & VM_WRITE)
 		entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3824,7 +3822,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
 
 	flush_icache_page(vma, page);
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (write)
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 	/* copy-on-write page */
-- 
2.17.1


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

* [PATCH] MIPS: make userspace mapping young by default
@ 2020-09-19  7:39 Huang Pei
  0 siblings, 0 replies; 19+ messages in thread
From: Huang Pei @ 2020-09-19  7:39 UTC (permalink / raw)
  To: Thomas Bogendoerfer, ambrosehua
  Cc: Bibo Mao, Andrew Morton, linux-mips, linux-arch, linux-mm,
	Jiaxun Yang, Paul Burton, Li Xuefeng, Yang Tiezhu, Gao Juxin,
	Fuxin Zhang, Huacai Chen

MIPS page fault path take 3 exceptions (1 TLB Miss + 2 TLB Invalid), but
the second TLB Invalid exception is just triggered by __update_tlb from
do_page_fault writing tlb without _PAGE_VALID set. With this patch, it
only take 1 TLB Miss + 1 TLB Invalid exceptions

This version removes pte_sw_mkyoung without polluting MM code and makes
page fault delay of MIPS on par with other architecture and covers both
no-RIXI and RIXI MIPS CPUS

[1]: https://lkml.kernel.org/lkml/1591416169-26666-1-git-send-email
-maobibo@loongson.cn/
---
V3:
- reformat with whitespace cleaned up following Thomas's advice
V2:
- remove unused asm-generic definition of pte_sw_mkyoung following Mao's
advice
---
Co-developed-by: Huang Pei <huangpei@loongson.cn>
Signed-off-by: Huang Pei <huangpei@loongson.cn>
Co-developed-by: Bibo Mao <maobibo@loonson.cn>
---
 arch/mips/include/asm/pgtable.h | 10 ++++------
 arch/mips/mm/cache.c            | 25 +++++++++++++------------
 include/linux/pgtable.h         |  8 --------
 mm/memory.c                     |  3 ---
 4 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index dd7a0f552cac..931fb35730f0 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -27,11 +27,11 @@ struct vm_area_struct;
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
 				 _page_cachable_default)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
-				 _page_cachable_default)
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
+				 __READABLE | _page_cachable_default)
 #define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
-				 _page_cachable_default)
-#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | \
+				 __READABLE | _page_cachable_default)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT |  __READABLE | \
 				 _page_cachable_default)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
 				 _PAGE_GLOBAL | _page_cachable_default)
@@ -414,8 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
 	return pte;
 }
 
-#define pte_sw_mkyoung	pte_mkyoung
-
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
 
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 3e81ba000096..ed75f2871aad 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -159,22 +159,23 @@ static inline void setup_protection_map(void)
 {
 	if (cpu_has_rixi) {
 		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
 		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
 
 		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
 		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
-		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
-		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
-		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
+		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | __READABLE);
+		protection_map[12]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[13]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[14]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+		protection_map[15]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+
 
 	} else {
 		protection_map[0] = PAGE_NONE;
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index e8cbc2e795d5..ef9c5fa8673e 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -377,14 +377,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
  * To be differentiate with macro pte_mkyoung, this macro is used on platforms
  * where software maintains page access bit.
  */
-#ifndef pte_sw_mkyoung
-static inline pte_t pte_sw_mkyoung(pte_t pte)
-{
-	return pte;
-}
-#define pte_sw_mkyoung	pte_sw_mkyoung
-#endif
-
 #ifndef pte_savedwrite
 #define pte_savedwrite pte_write
 #endif
diff --git a/mm/memory.c b/mm/memory.c
index 602f4283122f..5100ab5bcf77 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2705,7 +2705,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
-		entry = pte_sw_mkyoung(entry);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 		/*
 		 * Clear the pte entry and flush it first, before updating the
@@ -3386,7 +3385,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 	__SetPageUptodate(page);
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (vma->vm_flags & VM_WRITE)
 		entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3661,7 +3659,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
 
 	flush_icache_page(vma, page);
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (write)
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 	/* copy-on-write page */
-- 
2.17.1


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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2020-09-07 10:35   ` Huang Pei
@ 2020-09-07 13:10     ` maobibo
  0 siblings, 0 replies; 19+ messages in thread
From: maobibo @ 2020-09-07 13:10 UTC (permalink / raw)
  To: Huang Pei
  Cc: Thomas Bogendoerfer, ambrosehua, Andrew Morton, linux-mips,
	linux-arch, linux-mm, Jiaxun Yang, Paul Burton, Li Xuefeng,
	Yang Tiezhu, Gao Juxin, Fuxin Zhang, Huacai Chen



On 09/07/2020 06:35 PM, Huang Pei wrote:
> On Mon, Sep 07, 2020 at 04:50:45PM +0800, maobibo wrote:
>> Sorry for the late reply.
>>
>> Would you like to remove definition of macro pte_sw_mkyoung in header
>> file include/linux/pgtable.h, since it is not used any more.
>>
>> The others look good to me.
>>
>> regards
>> bibo,mao
>>
>> On 09/04/2020 04:49 PM, Huang Pei wrote:
>>> This version removes pte_sw_mkyoung without polluting MM code and covers
>>> both no-RIXI and RIXI MIPS CPUs and makes page fault delay of MIPS on par
>>> with other architecture 
>>>
>>> MIPS page fault path take 3 exceptions (1 TLB Miss + 2 TLB Invalid), but
>>> the second TLB Invalid exception is just triggered by __update_tlb from
>>> do_page_fault writing tlb without _PAGE_VALID set. By making userspace
>>> mapping young by default, aka _PAGE_VALID and _PAGE_ACCESSED both set in
>>> prot, it only take 1 TLB Miss + 1 TLB Invalid exceptions
>>>
>>> [1]: https://lkml.kernel.org/lkml/1591416169-26666-1-git-send-email
>>> -maobibo@loongson.cn/
>>>
>>> Co-developed-by: Bibo Mao <maobibo@loonson.cn>
>>> Co-developed-by: Huang Pei <huangpei@loongson.cn>
>>> Signed-off-by: Huang Pei <huangpei@loongson.cn>
>>> ---
>>>  arch/mips/include/asm/pgtable.h | 32 +++++++++++++++-----------------
>>>  arch/mips/mm/cache.c            | 25 +++++++++++++------------
>>>  mm/memory.c                     |  3 ---
>>>  3 files changed, 28 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
>>> index dd7a0f552cac..aaafe3d6a0a1 100644
>>> --- a/arch/mips/include/asm/pgtable.h
>>> +++ b/arch/mips/include/asm/pgtable.h
>>> @@ -25,22 +25,22 @@
>>>  struct mm_struct;
>>>  struct vm_area_struct;
>>>  
>>> -#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
>>> -				 _page_cachable_default)
>>> -#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
>>> -				 _page_cachable_default)
>>> -#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
>>> -				 _page_cachable_default)
>>> -#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | \
>>> -				 _page_cachable_default)
>>> -#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
>>> -				 _PAGE_GLOBAL | _page_cachable_default)
>>> -#define PAGE_KERNEL_NC	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
>>> -				 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
>>> -#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
>>> -				 _page_cachable_default)
>>> +#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
>>> +                                _page_cachable_default)
>>> +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
>>> +                                __READABLE | _page_cachable_default)
>>> +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
>>> +                                __READABLE | _page_cachable_default)
>>> +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT |  __READABLE | \
>>> +                                _page_cachable_default)
>>> +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
>>> +                                _PAGE_GLOBAL | _page_cachable_default)
>>> +#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
>>> +                                _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
>>> +#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
>>> +                                _page_cachable_default)
>>>  #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
>>> -			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
>>> +                       __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
>>>  
>>>  /*
>>>   * If _PAGE_NO_EXEC is not defined, we can't do page protection for
>>> @@ -414,8 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
>>>  	return pte;
>>>  }
>>>  
>>> -#define pte_sw_mkyoung	pte_mkyoung
>>> -
>>>  #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
>>>  static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
>>>  
>>> diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
>>> index 3e81ba000096..ed75f2871aad 100644
>>> --- a/arch/mips/mm/cache.c
>>> +++ b/arch/mips/mm/cache.c
>>> @@ -159,22 +159,23 @@ static inline void setup_protection_map(void)
>>>  {
>>>  	if (cpu_has_rixi) {
>>>  		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
>>> -		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
>>> +		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>>>  		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
>>> -		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
>>> -		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
>>> -		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
>>> -		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
>>> -		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
>>> +		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>>> +		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>>> +		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>>> +		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>>> +		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>>>  
>>>  		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
>>> -		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
>>> +		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>>>  		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
>>> -		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
>>> -		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
>>> -		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
>>> -		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
>>> -		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
>>> +		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | __READABLE);
>>> +		protection_map[12]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>>> +		protection_map[13]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>>> +		protection_map[14]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>>> +		protection_map[15]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>>> +
>>>  
>>>  	} else {
>>>  		protection_map[0] = PAGE_NONE;
>>> diff --git a/mm/memory.c b/mm/memory.c
>>> index 602f4283122f..5100ab5bcf77 100644
>>> --- a/mm/memory.c
>>> +++ b/mm/memory.c
>>> @@ -2705,7 +2705,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
>>>  		}
>>>  		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
>>>  		entry = mk_pte(new_page, vma->vm_page_prot);
>>> -		entry = pte_sw_mkyoung(entry);
>>>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>>>  		/*
>>>  		 * Clear the pte entry and flush it first, before updating the
>>> @@ -3386,7 +3385,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
>>>  	__SetPageUptodate(page);
>>>  
>>>  	entry = mk_pte(page, vma->vm_page_prot);
>>> -	entry = pte_sw_mkyoung(entry);
>>>  	if (vma->vm_flags & VM_WRITE)
>>>  		entry = pte_mkwrite(pte_mkdirty(entry));
>>>  
>>> @@ -3661,7 +3659,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
>>>  
>>>  	flush_icache_page(vma, page);
>>>  	entry = mk_pte(page, vma->vm_page_prot);
>>> -	entry = pte_sw_mkyoung(entry);
>>>  	if (write)
>>>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>>>  	/* copy-on-write page */
>>>
> 
> I search for pte_sw_mkyoung/pte_{clear,mk,}_savewrite, none of which is
> used, do I really need to remove pte_sw_mkyoung in this patch just for
> *not used* ?
> 
macro pte_sw_mkyoung is added by me previously, and it is defined as empty excepts mips
system. If it is not used any more on mips sytem, I suggest that it should be removed here.

regards
bibo,mao


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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2020-09-07  8:50 ` maobibo
@ 2020-09-07 10:35   ` Huang Pei
  2020-09-07 13:10     ` maobibo
  0 siblings, 1 reply; 19+ messages in thread
From: Huang Pei @ 2020-09-07 10:35 UTC (permalink / raw)
  To: maobibo
  Cc: Thomas Bogendoerfer, ambrosehua, Andrew Morton, linux-mips,
	linux-arch, linux-mm, Jiaxun Yang, Paul Burton, Li Xuefeng,
	Yang Tiezhu, Gao Juxin, Fuxin Zhang, Huacai Chen

On Mon, Sep 07, 2020 at 04:50:45PM +0800, maobibo wrote:
> Sorry for the late reply.
> 
> Would you like to remove definition of macro pte_sw_mkyoung in header
> file include/linux/pgtable.h, since it is not used any more.
> 
> The others look good to me.
> 
> regards
> bibo,mao
> 
> On 09/04/2020 04:49 PM, Huang Pei wrote:
> > This version removes pte_sw_mkyoung without polluting MM code and covers
> > both no-RIXI and RIXI MIPS CPUs and makes page fault delay of MIPS on par
> > with other architecture 
> > 
> > MIPS page fault path take 3 exceptions (1 TLB Miss + 2 TLB Invalid), but
> > the second TLB Invalid exception is just triggered by __update_tlb from
> > do_page_fault writing tlb without _PAGE_VALID set. By making userspace
> > mapping young by default, aka _PAGE_VALID and _PAGE_ACCESSED both set in
> > prot, it only take 1 TLB Miss + 1 TLB Invalid exceptions
> > 
> > [1]: https://lkml.kernel.org/lkml/1591416169-26666-1-git-send-email
> > -maobibo@loongson.cn/
> > 
> > Co-developed-by: Bibo Mao <maobibo@loonson.cn>
> > Co-developed-by: Huang Pei <huangpei@loongson.cn>
> > Signed-off-by: Huang Pei <huangpei@loongson.cn>
> > ---
> >  arch/mips/include/asm/pgtable.h | 32 +++++++++++++++-----------------
> >  arch/mips/mm/cache.c            | 25 +++++++++++++------------
> >  mm/memory.c                     |  3 ---
> >  3 files changed, 28 insertions(+), 32 deletions(-)
> > 
> > diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
> > index dd7a0f552cac..aaafe3d6a0a1 100644
> > --- a/arch/mips/include/asm/pgtable.h
> > +++ b/arch/mips/include/asm/pgtable.h
> > @@ -25,22 +25,22 @@
> >  struct mm_struct;
> >  struct vm_area_struct;
> >  
> > -#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
> > -				 _page_cachable_default)
> > -#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> > -				 _page_cachable_default)
> > -#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
> > -				 _page_cachable_default)
> > -#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | \
> > -				 _page_cachable_default)
> > -#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> > -				 _PAGE_GLOBAL | _page_cachable_default)
> > -#define PAGE_KERNEL_NC	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> > -				 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
> > -#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> > -				 _page_cachable_default)
> > +#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
> > +                                _page_cachable_default)
> > +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> > +                                __READABLE | _page_cachable_default)
> > +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
> > +                                __READABLE | _page_cachable_default)
> > +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT |  __READABLE | \
> > +                                _page_cachable_default)
> > +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> > +                                _PAGE_GLOBAL | _page_cachable_default)
> > +#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> > +                                _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
> > +#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> > +                                _page_cachable_default)
> >  #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
> > -			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
> > +                       __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
> >  
> >  /*
> >   * If _PAGE_NO_EXEC is not defined, we can't do page protection for
> > @@ -414,8 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
> >  	return pte;
> >  }
> >  
> > -#define pte_sw_mkyoung	pte_mkyoung
> > -
> >  #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
> >  static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
> >  
> > diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
> > index 3e81ba000096..ed75f2871aad 100644
> > --- a/arch/mips/mm/cache.c
> > +++ b/arch/mips/mm/cache.c
> > @@ -159,22 +159,23 @@ static inline void setup_protection_map(void)
> >  {
> >  	if (cpu_has_rixi) {
> >  		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> > -		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> > +		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> >  		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> > -		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> > -		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> > -		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> > -		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> > -		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> > +		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> > +		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> > +		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> > +		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> > +		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> >  
> >  		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> > -		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> > +		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> >  		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
> > -		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> > -		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> > -		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> > -		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
> > -		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
> > +		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | __READABLE);
> > +		protection_map[12]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> > +		protection_map[13]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> > +		protection_map[14]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> > +		protection_map[15]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> > +
> >  
> >  	} else {
> >  		protection_map[0] = PAGE_NONE;
> > diff --git a/mm/memory.c b/mm/memory.c
> > index 602f4283122f..5100ab5bcf77 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -2705,7 +2705,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
> >  		}
> >  		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
> >  		entry = mk_pte(new_page, vma->vm_page_prot);
> > -		entry = pte_sw_mkyoung(entry);
> >  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> >  		/*
> >  		 * Clear the pte entry and flush it first, before updating the
> > @@ -3386,7 +3385,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
> >  	__SetPageUptodate(page);
> >  
> >  	entry = mk_pte(page, vma->vm_page_prot);
> > -	entry = pte_sw_mkyoung(entry);
> >  	if (vma->vm_flags & VM_WRITE)
> >  		entry = pte_mkwrite(pte_mkdirty(entry));
> >  
> > @@ -3661,7 +3659,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
> >  
> >  	flush_icache_page(vma, page);
> >  	entry = mk_pte(page, vma->vm_page_prot);
> > -	entry = pte_sw_mkyoung(entry);
> >  	if (write)
> >  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> >  	/* copy-on-write page */
> > 

I search for pte_sw_mkyoung/pte_{clear,mk,}_savewrite, none of which is
used, do I really need to remove pte_sw_mkyoung in this patch just for
*not used* ?


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

* Re: [PATCH] MIPS: make userspace mapping young by default
  2020-09-04  8:49 Huang Pei
@ 2020-09-07  8:50 ` maobibo
  2020-09-07 10:35   ` Huang Pei
  0 siblings, 1 reply; 19+ messages in thread
From: maobibo @ 2020-09-07  8:50 UTC (permalink / raw)
  To: Huang Pei, Thomas Bogendoerfer, ambrosehua
  Cc: Andrew Morton, linux-mips, linux-arch, linux-mm, Jiaxun Yang,
	Paul Burton, Li Xuefeng, Yang Tiezhu, Gao Juxin, Fuxin Zhang,
	Huacai Chen

Sorry for the late reply.

Would you like to remove definition of macro pte_sw_mkyoung in header
file include/linux/pgtable.h, since it is not used any more.

The others look good to me.

regards
bibo,mao

On 09/04/2020 04:49 PM, Huang Pei wrote:
> This version removes pte_sw_mkyoung without polluting MM code and covers
> both no-RIXI and RIXI MIPS CPUs and makes page fault delay of MIPS on par
> with other architecture 
> 
> MIPS page fault path take 3 exceptions (1 TLB Miss + 2 TLB Invalid), but
> the second TLB Invalid exception is just triggered by __update_tlb from
> do_page_fault writing tlb without _PAGE_VALID set. By making userspace
> mapping young by default, aka _PAGE_VALID and _PAGE_ACCESSED both set in
> prot, it only take 1 TLB Miss + 1 TLB Invalid exceptions
> 
> [1]: https://lkml.kernel.org/lkml/1591416169-26666-1-git-send-email
> -maobibo@loongson.cn/
> 
> Co-developed-by: Bibo Mao <maobibo@loonson.cn>
> Co-developed-by: Huang Pei <huangpei@loongson.cn>
> Signed-off-by: Huang Pei <huangpei@loongson.cn>
> ---
>  arch/mips/include/asm/pgtable.h | 32 +++++++++++++++-----------------
>  arch/mips/mm/cache.c            | 25 +++++++++++++------------
>  mm/memory.c                     |  3 ---
>  3 files changed, 28 insertions(+), 32 deletions(-)
> 
> diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
> index dd7a0f552cac..aaafe3d6a0a1 100644
> --- a/arch/mips/include/asm/pgtable.h
> +++ b/arch/mips/include/asm/pgtable.h
> @@ -25,22 +25,22 @@
>  struct mm_struct;
>  struct vm_area_struct;
>  
> -#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
> -				 _page_cachable_default)
> -#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> -				 _page_cachable_default)
> -#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
> -				 _page_cachable_default)
> -#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | \
> -				 _page_cachable_default)
> -#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> -				 _PAGE_GLOBAL | _page_cachable_default)
> -#define PAGE_KERNEL_NC	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> -				 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
> -#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> -				 _page_cachable_default)
> +#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
> +                                _page_cachable_default)
> +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> +                                __READABLE | _page_cachable_default)
> +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
> +                                __READABLE | _page_cachable_default)
> +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT |  __READABLE | \
> +                                _page_cachable_default)
> +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> +                                _PAGE_GLOBAL | _page_cachable_default)
> +#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
> +                                _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
> +#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
> +                                _page_cachable_default)
>  #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
> -			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
> +                       __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
>  
>  /*
>   * If _PAGE_NO_EXEC is not defined, we can't do page protection for
> @@ -414,8 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
>  	return pte;
>  }
>  
> -#define pte_sw_mkyoung	pte_mkyoung
> -
>  #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
>  static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
>  
> diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
> index 3e81ba000096..ed75f2871aad 100644
> --- a/arch/mips/mm/cache.c
> +++ b/arch/mips/mm/cache.c
> @@ -159,22 +159,23 @@ static inline void setup_protection_map(void)
>  {
>  	if (cpu_has_rixi) {
>  		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> +		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>  		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> -		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> +		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> +		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> +		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> +		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> +		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
>  
>  		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
> -		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
> +		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
>  		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
> -		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
> -		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
> -		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
> -		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
> +		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | __READABLE);
> +		protection_map[12]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> +		protection_map[13]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
> +		protection_map[14]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> +		protection_map[15]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
> +
>  
>  	} else {
>  		protection_map[0] = PAGE_NONE;
> diff --git a/mm/memory.c b/mm/memory.c
> index 602f4283122f..5100ab5bcf77 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2705,7 +2705,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
>  		}
>  		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
>  		entry = mk_pte(new_page, vma->vm_page_prot);
> -		entry = pte_sw_mkyoung(entry);
>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>  		/*
>  		 * Clear the pte entry and flush it first, before updating the
> @@ -3386,7 +3385,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
>  	__SetPageUptodate(page);
>  
>  	entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
>  	if (vma->vm_flags & VM_WRITE)
>  		entry = pte_mkwrite(pte_mkdirty(entry));
>  
> @@ -3661,7 +3659,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
>  
>  	flush_icache_page(vma, page);
>  	entry = mk_pte(page, vma->vm_page_prot);
> -	entry = pte_sw_mkyoung(entry);
>  	if (write)
>  		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>  	/* copy-on-write page */
> 


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

* [PATCH] MIPS: make userspace mapping young by default
@ 2020-09-04  8:49 Huang Pei
  2020-09-07  8:50 ` maobibo
  0 siblings, 1 reply; 19+ messages in thread
From: Huang Pei @ 2020-09-04  8:49 UTC (permalink / raw)
  To: Thomas Bogendoerfer, ambrosehua
  Cc: Bibo Mao, Andrew Morton, linux-mips, linux-arch, linux-mm,
	Jiaxun Yang, Paul Burton, Li Xuefeng, Yang Tiezhu, Gao Juxin,
	Fuxin Zhang, Huacai Chen

This version removes pte_sw_mkyoung without polluting MM code and covers
both no-RIXI and RIXI MIPS CPUs and makes page fault delay of MIPS on par
with other architecture 

MIPS page fault path take 3 exceptions (1 TLB Miss + 2 TLB Invalid), but
the second TLB Invalid exception is just triggered by __update_tlb from
do_page_fault writing tlb without _PAGE_VALID set. By making userspace
mapping young by default, aka _PAGE_VALID and _PAGE_ACCESSED both set in
prot, it only take 1 TLB Miss + 1 TLB Invalid exceptions

[1]: https://lkml.kernel.org/lkml/1591416169-26666-1-git-send-email
-maobibo@loongson.cn/

Co-developed-by: Bibo Mao <maobibo@loonson.cn>
Co-developed-by: Huang Pei <huangpei@loongson.cn>
Signed-off-by: Huang Pei <huangpei@loongson.cn>
---
 arch/mips/include/asm/pgtable.h | 32 +++++++++++++++-----------------
 arch/mips/mm/cache.c            | 25 +++++++++++++------------
 mm/memory.c                     |  3 ---
 3 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index dd7a0f552cac..aaafe3d6a0a1 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -25,22 +25,22 @@
 struct mm_struct;
 struct vm_area_struct;
 
-#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
-				 _page_cachable_default)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
-				 _page_cachable_default)
-#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
-				 _page_cachable_default)
-#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | \
-				 _page_cachable_default)
-#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-				 _PAGE_GLOBAL | _page_cachable_default)
-#define PAGE_KERNEL_NC	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-				 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
-				 _page_cachable_default)
+#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_NO_READ | \
+                                _page_cachable_default)
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
+                                __READABLE | _page_cachable_default)
+#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_NO_EXEC | \
+                                __READABLE | _page_cachable_default)
+#define PAGE_READONLY  __pgprot(_PAGE_PRESENT |  __READABLE | \
+                                _page_cachable_default)
+#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+                                _PAGE_GLOBAL | _page_cachable_default)
+#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+                                _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
+                                _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
-			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
+                       __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
 /*
  * If _PAGE_NO_EXEC is not defined, we can't do page protection for
@@ -414,8 +414,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
 	return pte;
 }
 
-#define pte_sw_mkyoung	pte_mkyoung
-
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
 
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 3e81ba000096..ed75f2871aad 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -159,22 +159,23 @@ static inline void setup_protection_map(void)
 {
 	if (cpu_has_rixi) {
 		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
 		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[6]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[7]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
 
 		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
-		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
 		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
-		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
-		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-		protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
-		protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
+		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | __READABLE);
+		protection_map[12]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[13]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | __READABLE);
+		protection_map[14]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+		protection_map[15]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | __READABLE);
+
 
 	} else {
 		protection_map[0] = PAGE_NONE;
diff --git a/mm/memory.c b/mm/memory.c
index 602f4283122f..5100ab5bcf77 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2705,7 +2705,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 		}
 		flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
-		entry = pte_sw_mkyoung(entry);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 		/*
 		 * Clear the pte entry and flush it first, before updating the
@@ -3386,7 +3385,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 	__SetPageUptodate(page);
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (vma->vm_flags & VM_WRITE)
 		entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3661,7 +3659,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page)
 
 	flush_icache_page(vma, page);
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = pte_sw_mkyoung(entry);
 	if (write)
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 	/* copy-on-write page */
-- 
2.17.1


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

end of thread, other threads:[~2021-02-08 19:51 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-06  4:02 [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Bibo Mao
2020-06-06  4:02 ` [PATCH v2 2/2] MIPS: Add writable-applies-readable policy with pgrot Bibo Mao
2020-07-26  8:32 ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on platforms with RIXI Thomas Bogendoerfer
2020-08-25  3:20   ` [PATCH v2 1/2] MIPS: Set page access bit with pgprot on Huang Pei
2020-08-25  3:20     ` [PATCH] MIPS: make userspace mapping young by default Huang Pei
2020-09-04  8:49 Huang Pei
2020-09-07  8:50 ` maobibo
2020-09-07 10:35   ` Huang Pei
2020-09-07 13:10     ` maobibo
2020-09-19  7:39 Huang Pei
2021-02-04  1:39 Huang Pei
2021-02-04  3:29 ` Nicholas Piggin
2021-02-04  4:46   ` 黄沛
2021-02-04 10:34   ` Thomas Bogendoerfer
2021-02-04 11:27     ` Nicholas Piggin
2021-02-04 15:22 ` Thomas Bogendoerfer
2021-02-05 23:41   ` Andrew Morton
2021-02-08 17:44     ` Christophe Leroy
2021-02-08 19:48       ` Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).