linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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; 15+ 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] 15+ messages in thread

* Re: [PATCH] MIPS: make userspace mapping young by default
  2020-09-04  8:49 [PATCH] MIPS: make userspace mapping young by default Huang Pei
@ 2020-09-07  8:50 ` maobibo
  2020-09-07 10:35   ` Huang Pei
  0 siblings, 1 reply; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ messages in thread

* [PATCH] MIPS: make userspace mapping young by default
@ 2020-09-19  7:39 Huang Pei
  0 siblings, 0 replies; 15+ 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] 15+ 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; 15+ 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] 15+ messages in thread

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

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-04  8:49 [PATCH] MIPS: make userspace mapping young by default Huang Pei
2020-09-07  8:50 ` maobibo
2020-09-07 10:35   ` Huang Pei
2020-09-07 13:10     ` maobibo
  -- strict thread matches above, loose matches on Subject: below --
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
2020-09-19  7:39 Huang Pei
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

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