* [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
* Re: [PATCH] MIPS: make userspace mapping young by default
2021-02-04 1:39 [PATCH] MIPS: make userspace mapping young by default 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
* 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 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 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 1:39 [PATCH] MIPS: make userspace mapping young by default 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 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-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-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
* [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
* 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
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-04 8:49 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
* [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
* [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 --
2021-02-04 1:39 [PATCH] MIPS: make userspace mapping young by default 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
-- strict thread matches above, loose matches on Subject: below --
2020-09-19 7:39 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-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).