Re: [PATCH 2/8] opeinrisc: switch to generic version of pte allocation

2020-06-27 Thread Stafford Horne
On Sat, Jun 27, 2020 at 05:34:47PM +0300, Mike Rapoport wrote:
> From: Mike Rapoport 
> 
> Replace pte_alloc_one(), pte_free() and pte_free_kernel() with the generic
> implementation. The only actual functional change is the addition of
> __GFP_ACCOUT for the allocation of the user page tables.
> 
> The pte_alloc_one_kernel() is kept back because its implementation on
> openrisc is different than the generic one.
> 
> Signed-off-by: Mike Rapoport 

Thank's for this.

Acked-by: Stafford Horne 

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [PATCH 4/8] asm-generic: pgalloc: provide generic pmd_alloc_one() and pmd_free_one()

2020-06-27 Thread Matthew Wilcox
On Sat, Jun 27, 2020 at 05:34:49PM +0300, Mike Rapoport wrote:
> More elaborate versions on arm64 and x86 account memory for the user page
> tables and call to pgtable_pmd_page_ctor() as the part of PMD page
> initialization.
> 
> Move the arm64 version to include/asm-generic/pgalloc.h and use the generic
> version on several architectures.
> 
> The pgtable_pmd_page_ctor() is a NOP when ARCH_ENABLE_SPLIT_PMD_PTLOCK is
> not enabled, so there is no functional change for most architectures except
> of the addition of __GFP_ACCOUNT for allocation of user page tables.

Thanks for including this line; it reminded me that we're not setting
the PageTable flag on the page, nor accounting it to the zone page stats.
Hope you don't mind me tagging a patch to do that on as 9/8.

We could also do with a pud_page_[cd]tor and maybe even p4d/pgd versions.
But that brings me to the next question -- could/should some of this
be moved over to asm-generic/pgalloc.h?  The ctor/dtor aren't called
from anywhere else, and there's value to reducing the total amount of
code in mm.h, but then there's also value to keeping all the ifdef
ARCH_ENABLE_SPLIT_PMD_PTLOCK code together too.  So I'm a bit torn.
What do you think?

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 9/8] mm: Account PMD tables like PTE tables

2020-06-27 Thread Matthew Wilcox
We account the PTE level of the page tables to the process in order to
make smarter OOM decisions and help diagnose why memory is fragmented.
For these same reasons, we should account pages allocated for PMDs.
With larger process address spaces and ASLR, the number of PMDs in use
is higher than it used to be so the inaccuracy is starting to matter.

Signed-off-by: Matthew Wilcox (Oracle) 
---
 include/linux/mm.h | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index dc7b87310c10..b283e25fcffa 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2271,7 +2271,7 @@ static inline spinlock_t *pmd_lockptr(struct mm_struct 
*mm, pmd_t *pmd)
return ptlock_ptr(pmd_to_page(pmd));
 }
 
-static inline bool pgtable_pmd_page_ctor(struct page *page)
+static inline bool pmd_ptlock_init(struct page *page)
 {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
page->pmd_huge_pte = NULL;
@@ -2279,7 +2279,7 @@ static inline bool pgtable_pmd_page_ctor(struct page 
*page)
return ptlock_init(page);
 }
 
-static inline void pgtable_pmd_page_dtor(struct page *page)
+static inline void pmd_ptlock_free(struct page *page)
 {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
VM_BUG_ON_PAGE(page->pmd_huge_pte, page);
@@ -2296,8 +2296,8 @@ static inline spinlock_t *pmd_lockptr(struct mm_struct 
*mm, pmd_t *pmd)
return >page_table_lock;
 }
 
-static inline bool pgtable_pmd_page_ctor(struct page *page) { return true; }
-static inline void pgtable_pmd_page_dtor(struct page *page) {}
+static inline bool pmd_ptlock_init(struct page *page) { return true; }
+static inline void pmd_ptlock_free(struct page *page) {}
 
 #define pmd_huge_pte(mm, pmd) ((mm)->pmd_huge_pte)
 
@@ -2310,6 +2310,22 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, 
pmd_t *pmd)
return ptl;
 }
 
+static inline bool pgtable_pmd_page_ctor(struct page *page)
+{
+   if (!pmd_ptlock_init(page))
+   return false;
+   __SetPageTable(page);
+   inc_zone_page_state(page, NR_PAGETABLE);
+   return true;
+}
+
+static inline void pgtable_pmd_page_dtor(struct page *page)
+{
+   pmd_ptlock_free(page);
+   __ClearPageTable(page);
+   dec_zone_page_state(page, NR_PAGETABLE);
+}
+
 /*
  * No scalability reason to split PUD locks yet, but follow the same pattern
  * as the PMD locks to make it easier if we decide to.  The VM should not be
-- 
2.27.0


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [PATCH 0/8] mm: cleanup usage of

2020-06-27 Thread Matthew Wilcox
On Sat, Jun 27, 2020 at 05:34:45PM +0300, Mike Rapoport wrote:
> Most architectures have very similar versions of pXd_alloc_one() and
> pXd_free_one() for intermediate levels of page table. 
> These patches add generic versions of these functions in
>  and enable use of the generic functions where
> appropriate.

For the series:

Reviewed-by: Matthew Wilcox (Oracle) 

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 8/8] mm: move p?d_alloc_track to separate header file

2020-06-27 Thread Mike Rapoport
From: Joerg Roedel 

The functions are only used in two source files, both residing in mm/
subdirectory, so there is no need for them to be in the global 
header.  Move them to the new mm/pgalloc-track.h header and include it only
where needed.

[rppt: mv include/linux/pgalloc-track.h mm/]

Link: http://lkml.kernel.org/r/20200609120533.25867-1-j...@8bytes.org
Signed-off-by: Joerg Roedel 
Cc: Peter Zijlstra (Intel) 
Cc: Andy Lutomirski 
Cc: Abdul Haleem 
Cc: Satheesh Rajendran 
Cc: Stephen Rothwell 
Cc: Steven Rostedt (VMware) 
Cc: Mike Rapoport 
Cc: Christophe Leroy 
Signed-off-by: Mike Rapoport 
---
 include/linux/mm.h | 45 
 mm/ioremap.c   |  2 ++
 mm/pgalloc-track.h | 51 ++
 mm/vmalloc.c   |  1 +
 4 files changed, 54 insertions(+), 45 deletions(-)
 create mode 100644 mm/pgalloc-track.h

diff --git a/include/linux/mm.h b/include/linux/mm.h
index dc7b87310c10..5e878a3c7c57 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2093,51 +2093,11 @@ static inline pud_t *pud_alloc(struct mm_struct *mm, 
p4d_t *p4d,
NULL : pud_offset(p4d, address);
 }
 
-static inline p4d_t *p4d_alloc_track(struct mm_struct *mm, pgd_t *pgd,
-unsigned long address,
-pgtbl_mod_mask *mod_mask)
-
-{
-   if (unlikely(pgd_none(*pgd))) {
-   if (__p4d_alloc(mm, pgd, address))
-   return NULL;
-   *mod_mask |= PGTBL_PGD_MODIFIED;
-   }
-
-   return p4d_offset(pgd, address);
-}
-
-static inline pud_t *pud_alloc_track(struct mm_struct *mm, p4d_t *p4d,
-unsigned long address,
-pgtbl_mod_mask *mod_mask)
-{
-   if (unlikely(p4d_none(*p4d))) {
-   if (__pud_alloc(mm, p4d, address))
-   return NULL;
-   *mod_mask |= PGTBL_P4D_MODIFIED;
-   }
-
-   return pud_offset(p4d, address);
-}
-
 static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long 
address)
 {
return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
NULL: pmd_offset(pud, address);
 }
-
-static inline pmd_t *pmd_alloc_track(struct mm_struct *mm, pud_t *pud,
-unsigned long address,
-pgtbl_mod_mask *mod_mask)
-{
-   if (unlikely(pud_none(*pud))) {
-   if (__pmd_alloc(mm, pud, address))
-   return NULL;
-   *mod_mask |= PGTBL_PUD_MODIFIED;
-   }
-
-   return pmd_offset(pud, address);
-}
 #endif /* CONFIG_MMU */
 
 #if USE_SPLIT_PTE_PTLOCKS
@@ -2253,11 +2213,6 @@ static inline void pgtable_pte_page_dtor(struct page 
*page)
((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd))? \
NULL: pte_offset_kernel(pmd, address))
 
-#define pte_alloc_kernel_track(pmd, address, mask) \
-   ((unlikely(pmd_none(*(pmd))) && \
- (__pte_alloc_kernel(pmd) || ({*(mask)|=PGTBL_PMD_MODIFIED;0;})))?\
-   NULL: pte_offset_kernel(pmd, address))
-
 #if USE_SPLIT_PMD_PTLOCKS
 
 static struct page *pmd_to_page(pmd_t *pmd)
diff --git a/mm/ioremap.c b/mm/ioremap.c
index 5ee3526f71b8..5fa1ab41d152 100644
--- a/mm/ioremap.c
+++ b/mm/ioremap.c
@@ -13,6 +13,8 @@
 #include 
 #include 
 
+#include "pgalloc-track.h"
+
 #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
 static int __read_mostly ioremap_p4d_capable;
 static int __read_mostly ioremap_pud_capable;
diff --git a/mm/pgalloc-track.h b/mm/pgalloc-track.h
new file mode 100644
index ..1dcc865029a2
--- /dev/null
+++ b/mm/pgalloc-track.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_PGALLLC_TRACK_H
+#define _LINUX_PGALLLC_TRACK_H
+
+#if defined(CONFIG_MMU)
+static inline p4d_t *p4d_alloc_track(struct mm_struct *mm, pgd_t *pgd,
+unsigned long address,
+pgtbl_mod_mask *mod_mask)
+{
+   if (unlikely(pgd_none(*pgd))) {
+   if (__p4d_alloc(mm, pgd, address))
+   return NULL;
+   *mod_mask |= PGTBL_PGD_MODIFIED;
+   }
+
+   return p4d_offset(pgd, address);
+}
+
+static inline pud_t *pud_alloc_track(struct mm_struct *mm, p4d_t *p4d,
+unsigned long address,
+pgtbl_mod_mask *mod_mask)
+{
+   if (unlikely(p4d_none(*p4d))) {
+   if (__pud_alloc(mm, p4d, address))
+   return NULL;
+   *mod_mask |= PGTBL_P4D_MODIFIED;
+   }
+
+   return pud_offset(p4d, address);
+}
+
+static inline pmd_t *pmd_alloc_track(struct mm_struct *mm, pud_t *pud,
+unsigned long address,
+pgtbl_mod_mask *mod_mask)
+{

[PATCH 5/8] asm-generic: pgalloc: provide generic pud_alloc_one() and pud_free_one()

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

Several architectures define pud_alloc_one() as a wrapper for
__get_free_page() and pud_free() as a wrapper for free_page().

Provide a generic implementation in asm-generic/pgalloc.h and use it where
appropriate.

Signed-off-by: Mike Rapoport 
---
 arch/arm64/include/asm/pgalloc.h | 11 ---
 arch/ia64/include/asm/pgalloc.h  |  9 -
 arch/mips/include/asm/pgalloc.h  |  6 +-
 arch/x86/include/asm/pgalloc.h   | 15 ---
 include/asm-generic/pgalloc.h| 30 ++
 5 files changed, 31 insertions(+), 40 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 7246d0a662e1..0965945b595d 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -37,17 +37,6 @@ static inline void __pud_populate(pud_t *pudp, phys_addr_t 
pmdp, pudval_t prot)
 
 #if CONFIG_PGTABLE_LEVELS > 3
 
-static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-   return (pud_t *)__get_free_page(GFP_PGTABLE_USER);
-}
-
-static inline void pud_free(struct mm_struct *mm, pud_t *pudp)
-{
-   BUG_ON((unsigned long)pudp & (PAGE_SIZE-1));
-   free_page((unsigned long)pudp);
-}
-
 static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
 {
set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
index 5da1fc76477b..06f80358e20f 100644
--- a/arch/ia64/include/asm/pgalloc.h
+++ b/arch/ia64/include/asm/pgalloc.h
@@ -41,15 +41,6 @@ p4d_populate(struct mm_struct *mm, p4d_t * p4d_entry, pud_t 
* pud)
p4d_val(*p4d_entry) = __pa(pud);
 }
 
-static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-   return (pud_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-}
-
-static inline void pud_free(struct mm_struct *mm, pud_t *pud)
-{
-   free_page((unsigned long)pud);
-}
 #define __pud_free_tlb(tlb, pud, address)  pud_free((tlb)->mm, pud)
 #endif /* CONFIG_PGTABLE_LEVELS == 4 */
 
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
index eed1b3e8c642..e5a840910ce0 100644
--- a/arch/mips/include/asm/pgalloc.h
+++ b/arch/mips/include/asm/pgalloc.h
@@ -14,6 +14,7 @@
 #include 
 
 #define __HAVE_ARCH_PMD_ALLOC_ONE
+#define __HAVE_ARCH_PUD_ALLOC_ONE
 #include 
 
 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
@@ -87,11 +88,6 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, 
unsigned long address)
return pud;
 }
 
-static inline void pud_free(struct mm_struct *mm, pud_t *pud)
-{
-   free_pages((unsigned long)pud, PUD_ORDER);
-}
-
 static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud)
 {
set_p4d(p4d, __p4d((unsigned long)pud));
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
index 25feaa117c40..3d1085a14347 100644
--- a/arch/x86/include/asm/pgalloc.h
+++ b/arch/x86/include/asm/pgalloc.h
@@ -123,21 +123,6 @@ static inline void p4d_populate_safe(struct mm_struct *mm, 
p4d_t *p4d, pud_t *pu
set_p4d_safe(p4d, __p4d(_PAGE_TABLE | __pa(pud)));
 }
 
-static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-   gfp_t gfp = GFP_KERNEL_ACCOUNT;
-
-   if (mm == _mm)
-   gfp &= ~__GFP_ACCOUNT;
-   return (pud_t *)get_zeroed_page(gfp);
-}
-
-static inline void pud_free(struct mm_struct *mm, pud_t *pud)
-{
-   BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
-   free_page((unsigned long)pud);
-}
-
 extern void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud);
 
 static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 1bc027891a00..d361574aaadf 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -145,6 +145,36 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t 
*pmd)
 
 #endif /* CONFIG_PGTABLE_LEVELS > 2 */
 
+#if CONFIG_PGTABLE_LEVELS > 3
+
+#ifndef __HAVE_ARCH_PUD_FREE
+/**
+ * pud_alloc_one - allocate a page for PUD-level page table
+ * @mm: the mm_struct of the current context
+ *
+ * Allocates a page using %GFP_PGTABLE_USER for user context and
+ * %GFP_PGTABLE_KERNEL for kernel context.
+ *
+ * Return: pointer to the allocated memory or %NULL on error
+ */
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+   gfp_t gfp = GFP_PGTABLE_USER;
+
+   if (mm == _mm)
+   gfp = GFP_PGTABLE_KERNEL;
+   return (pud_t *)get_zeroed_page(gfp);
+}
+#endif
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+   BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
+   free_page((unsigned long)pud);
+}
+
+#endif /* CONFIG_PGTABLE_LEVELS > 3 */
+
 #endif /* CONFIG_MMU */
 
 #endif /* __ASM_GENERIC_PGALLOC_H */
-- 
2.26.2


___

[PATCH 6/8] asm-generic: pgalloc: provide generic pgd_free()

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

Most architectures define pgd_free() as a wrapper for free_page().

Provide a generic version in asm-generic/pgalloc.h and enable its use for
most architectures.

Signed-off-by: Mike Rapoport 
---
 arch/alpha/include/asm/pgalloc.h  | 6 --
 arch/arm/include/asm/pgalloc.h| 1 +
 arch/arm64/include/asm/pgalloc.h  | 1 +
 arch/csky/include/asm/pgalloc.h   | 7 +--
 arch/hexagon/include/asm/pgalloc.h| 7 +--
 arch/ia64/include/asm/pgalloc.h   | 5 -
 arch/m68k/include/asm/sun3_pgalloc.h  | 7 +--
 arch/microblaze/include/asm/pgalloc.h | 6 --
 arch/mips/include/asm/pgalloc.h   | 5 -
 arch/nds32/mm/mm-nds32.c  | 2 ++
 arch/nios2/include/asm/pgalloc.h  | 7 +--
 arch/parisc/include/asm/pgalloc.h | 1 +
 arch/riscv/include/asm/pgalloc.h  | 5 -
 arch/sh/include/asm/pgalloc.h | 1 +
 arch/um/include/asm/pgalloc.h | 1 -
 arch/um/kernel/mem.c  | 5 -
 arch/x86/include/asm/pgalloc.h| 1 +
 arch/xtensa/include/asm/pgalloc.h | 5 -
 include/asm-generic/pgalloc.h | 7 +++
 19 files changed, 18 insertions(+), 62 deletions(-)

diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h
index 4834cd52e9d0..9c6a24fe493d 100644
--- a/arch/alpha/include/asm/pgalloc.h
+++ b/arch/alpha/include/asm/pgalloc.h
@@ -34,10 +34,4 @@ pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
 
-static inline void
-pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-   free_page((unsigned long)pgd);
-}
-
 #endif /* _ALPHA_PGALLOC_H */
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index c5bdfd404ea5..15f4674715f8 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -65,6 +65,7 @@ static inline void clean_pte_table(pte_t *pte)
 
 #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
 #define __HAVE_ARCH_PTE_ALLOC_ONE
+#define __HAVE_ARCH_PGD_FREE
 #include 
 
 static inline pte_t *
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 0965945b595d..3c6a7f5988b1 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -13,6 +13,7 @@
 #include 
 #include 
 
+#define __HAVE_ARCH_PGD_FREE
 #include 
 
 #define PGD_SIZE   (PTRS_PER_PGD * sizeof(pgd_t))
diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h
index c7c1ed27e348..d58d8146b729 100644
--- a/arch/csky/include/asm/pgalloc.h
+++ b/arch/csky/include/asm/pgalloc.h
@@ -9,7 +9,7 @@
 #include 
 
 #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
-#include/* for pte_{alloc,free}_one */
+#include 
 
 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
pte_t *pte)
@@ -42,11 +42,6 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct 
*mm)
return pte;
 }
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-   free_pages((unsigned long)pgd, PGD_ORDER);
-}
-
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
pgd_t *ret;
diff --git a/arch/hexagon/include/asm/pgalloc.h 
b/arch/hexagon/include/asm/pgalloc.h
index cc9be514a676..f0c47e6a7427 100644
--- a/arch/hexagon/include/asm/pgalloc.h
+++ b/arch/hexagon/include/asm/pgalloc.h
@@ -11,7 +11,7 @@
 #include 
 #include 
 
-#include/* for pte_{alloc,free}_one */
+#include 
 
 extern unsigned long long kmap_generation;
 
@@ -41,11 +41,6 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
return pgd;
 }
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-   free_page((unsigned long) pgd);
-}
-
 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
pgtable_t pte)
 {
diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
index 06f80358e20f..9601cfe83c94 100644
--- a/arch/ia64/include/asm/pgalloc.h
+++ b/arch/ia64/include/asm/pgalloc.h
@@ -29,11 +29,6 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
return (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 }
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-   free_page((unsigned long)pgd);
-}
-
 #if CONFIG_PGTABLE_LEVELS == 4
 static inline void
 p4d_populate(struct mm_struct *mm, p4d_t * p4d_entry, pud_t * pud)
diff --git a/arch/m68k/include/asm/sun3_pgalloc.h 
b/arch/m68k/include/asm/sun3_pgalloc.h
index 11b95dadf7c0..000f64869b91 100644
--- a/arch/m68k/include/asm/sun3_pgalloc.h
+++ b/arch/m68k/include/asm/sun3_pgalloc.h
@@ -13,7 +13,7 @@
 
 #include 
 
-#include/* for pte_{alloc,free}_one */
+#include 
 
 extern const char bad_pmd_string[];
 
@@ -40,11 +40,6 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t 
*pmd, pgtable_t page
  */
 #define pmd_free(mm, x)do { } while (0)
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{

[PATCH 7/8] mm: move lib/ioremap.c to mm/

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

The functionality in lib/ioremap.c deals with pagetables, vmalloc and
caches, so it naturally belongs to mm/
Moving it there will also allow declaring p?d_alloc_track functions in an
header file inside mm/ rather than having those declarations in
include/linux/mm.h

Suggested-by: Andrew Morton 
Signed-off-by: Mike Rapoport 
---
 lib/Makefile  | 1 -
 mm/Makefile   | 2 +-
 {lib => mm}/ioremap.c | 0
 3 files changed, 1 insertion(+), 2 deletions(-)
 rename {lib => mm}/ioremap.c (100%)

diff --git a/lib/Makefile b/lib/Makefile
index b1c42c10073b..5f9384adde9c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -37,7 +37,6 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o
 
 lib-$(CONFIG_PRINTK) += dump_stack.o
-lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
 
 lib-y  += kobject.o klist.o
diff --git a/mm/Makefile b/mm/Makefile
index 6e9d46b2efc9..d5649f1c12c0 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -38,7 +38,7 @@ mmu-y := nommu.o
 mmu-$(CONFIG_MMU)  := highmem.o memory.o mincore.o \
   mlock.o mmap.o mmu_gather.o mprotect.o mremap.o \
   msync.o page_vma_mapped.o pagewalk.o \
-  pgtable-generic.o rmap.o vmalloc.o
+  pgtable-generic.o rmap.o vmalloc.o ioremap.o
 
 
 ifdef CONFIG_CROSS_MEMORY_ATTACH
diff --git a/lib/ioremap.c b/mm/ioremap.c
similarity index 100%
rename from lib/ioremap.c
rename to mm/ioremap.c
-- 
2.26.2


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 4/8] asm-generic: pgalloc: provide generic pmd_alloc_one() and pmd_free_one()

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

For most architectures that support >2 levels of page tables,
pmd_alloc_one() is a wrapper for __get_free_pages(), sometimes with
__GFP_ZERO and sometimes followed by memset(0) instead.

More elaborate versions on arm64 and x86 account memory for the user page
tables and call to pgtable_pmd_page_ctor() as the part of PMD page
initialization.

Move the arm64 version to include/asm-generic/pgalloc.h and use the generic
version on several architectures.

The pgtable_pmd_page_ctor() is a NOP when ARCH_ENABLE_SPLIT_PMD_PTLOCK is
not enabled, so there is no functional change for most architectures except
of the addition of __GFP_ACCOUNT for allocation of user page tables.

The pmd_free() is a wrapper for free_page() in all the cases, so no
functional change here.

Signed-off-by: Mike Rapoport 
---
 arch/alpha/include/asm/pgalloc.h | 15 +-
 arch/arm/include/asm/pgalloc.h   | 11 ---
 arch/arm64/include/asm/pgalloc.h | 27 +
 arch/ia64/include/asm/pgalloc.h  | 10 ---
 arch/mips/include/asm/pgalloc.h  |  8 ++
 arch/parisc/include/asm/pgalloc.h| 11 ++-
 arch/riscv/include/asm/pgalloc.h | 13 +
 arch/sh/include/asm/pgalloc.h|  3 ++
 arch/um/include/asm/pgalloc.h|  8 +-
 arch/um/include/asm/pgtable-3level.h |  3 --
 arch/um/kernel/mem.c | 12 
 arch/x86/include/asm/pgalloc.h   | 26 +
 include/asm-generic/pgalloc.h| 43 
 13 files changed, 55 insertions(+), 135 deletions(-)

diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h
index a1a29f60934c..4834cd52e9d0 100644
--- a/arch/alpha/include/asm/pgalloc.h
+++ b/arch/alpha/include/asm/pgalloc.h
@@ -5,7 +5,7 @@
 #include 
 #include 
 
-#include/* for pte_{alloc,free}_one */
+#include 
 
 /*  
  * Allocate and free page tables. The xxx_kernel() versions are
@@ -40,17 +40,4 @@ pgd_free(struct mm_struct *mm, pgd_t *pgd)
free_page((unsigned long)pgd);
 }
 
-static inline pmd_t *
-pmd_alloc_one(struct mm_struct *mm, unsigned long address)
-{
-   pmd_t *ret = (pmd_t *)__get_free_page(GFP_PGTABLE_USER);
-   return ret;
-}
-
-static inline void
-pmd_free(struct mm_struct *mm, pmd_t *pmd)
-{
-   free_page((unsigned long)pmd);
-}
-
 #endif /* _ALPHA_PGALLOC_H */
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 069da393110c..c5bdfd404ea5 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -22,17 +22,6 @@
 
 #ifdef CONFIG_ARM_LPAE
 
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-   return (pmd_t *)get_zeroed_page(GFP_KERNEL);
-}
-
-static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
-{
-   BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
-   free_page((unsigned long)pmd);
-}
-
 static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 58e93583ddb6..7246d0a662e1 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -13,37 +13,12 @@
 #include 
 #include 
 
-#include/* for pte_{alloc,free}_one */
+#include 
 
 #define PGD_SIZE   (PTRS_PER_PGD * sizeof(pgd_t))
 
 #if CONFIG_PGTABLE_LEVELS > 2
 
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-   gfp_t gfp = GFP_PGTABLE_USER;
-   struct page *page;
-
-   if (mm == _mm)
-   gfp = GFP_PGTABLE_KERNEL;
-
-   page = alloc_page(gfp);
-   if (!page)
-   return NULL;
-   if (!pgtable_pmd_page_ctor(page)) {
-   __free_page(page);
-   return NULL;
-   }
-   return page_address(page);
-}
-
-static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
-{
-   BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
-   pgtable_pmd_page_dtor(virt_to_page(pmdp));
-   free_page((unsigned long)pmdp);
-}
-
 static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
 {
set_pud(pudp, __pud(__phys_to_pud_val(pmdp) | prot));
diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
index 2a3050345099..5da1fc76477b 100644
--- a/arch/ia64/include/asm/pgalloc.h
+++ b/arch/ia64/include/asm/pgalloc.h
@@ -59,16 +59,6 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t 
* pmd)
pud_val(*pud_entry) = __pa(pmd);
 }
 
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-   return (pmd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-}
-
-static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
-{
-   free_page((unsigned long)pmd);
-}
-
 #define __pmd_free_tlb(tlb, pmd, address)  pmd_free((tlb)->mm, pmd)
 
 static inline void
diff --git a/arch/mips/include/asm/pgalloc.h 

[PATCH 3/8] xtensa: switch to generic version of pte allocation

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

xtensa clears PTEs during allocation of the page tables and pte_clear()
sets the PTE to a non-zero value. Splitting ptes_clear() helper out of
pte_alloc_one() and pte_alloc_one_kernel() allows reuse of base generic
allocation methods (__pte_alloc_one() and __pte_alloc_one_kernel()) and the
common GFP mask for page table allocations.

The pte_free() and pte_free_kernel() implementations on xtensa are
identical to the generic ones and can be dropped.

Signed-off-by: Mike Rapoport 
---
 arch/xtensa/include/asm/pgalloc.h | 41 ++-
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/arch/xtensa/include/asm/pgalloc.h 
b/arch/xtensa/include/asm/pgalloc.h
index 1d38f0e755ba..60ee94b42850 100644
--- a/arch/xtensa/include/asm/pgalloc.h
+++ b/arch/xtensa/include/asm/pgalloc.h
@@ -8,9 +8,14 @@
 #ifndef _XTENSA_PGALLOC_H
 #define _XTENSA_PGALLOC_H
 
+#ifdef CONFIG_MMU
 #include 
 #include 
 
+#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
+#define __HAVE_ARCH_PTE_ALLOC_ONE
+#include 
+
 /*
  * Allocating and freeing a pmd is trivial: the 1-entry pmd is
  * inside the pgd, so has no extra memory associated with it.
@@ -33,45 +38,37 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t 
*pgd)
free_page((unsigned long)pgd);
 }
 
+static inline void ptes_clear(pte_t *ptep)
+{
+   int i;
+
+   for (i = 0; i < PTRS_PER_PTE; i++)
+   pte_clear(NULL, 0, ptep + i);
+}
+
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
pte_t *ptep;
-   int i;
 
-   ptep = (pte_t *)__get_free_page(GFP_KERNEL);
+   ptep = (pte_t *)__pte_alloc_one_kernel(mm);
if (!ptep)
return NULL;
-   for (i = 0; i < 1024; i++)
-   pte_clear(NULL, 0, ptep + i);
+   ptes_clear(ptep);
return ptep;
 }
 
 static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
-   pte_t *pte;
struct page *page;
 
-   pte = pte_alloc_one_kernel(mm);
-   if (!pte)
-   return NULL;
-   page = virt_to_page(pte);
-   if (!pgtable_pte_page_ctor(page)) {
-   __free_page(page);
+   page = __pte_alloc_one(mm, GFP_PGTABLE_USER);
+   if (!page)
return NULL;
-   }
+   ptes_clear(page_address(page));
return page;
 }
 
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
-{
-   free_page((unsigned long)pte);
-}
-
-static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
-{
-   pgtable_pte_page_dtor(pte);
-   __free_page(pte);
-}
 #define pmd_pgtable(pmd) pmd_page(pmd)
+#endif CONFIG_MMU
 
 #endif /* _XTENSA_PGALLOC_H */
-- 
2.26.2


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 2/8] opeinrisc: switch to generic version of pte allocation

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

Replace pte_alloc_one(), pte_free() and pte_free_kernel() with the generic
implementation. The only actual functional change is the addition of
__GFP_ACCOUT for the allocation of the user page tables.

The pte_alloc_one_kernel() is kept back because its implementation on
openrisc is different than the generic one.

Signed-off-by: Mike Rapoport 
---
 arch/openrisc/include/asm/pgalloc.h | 33 +++--
 1 file changed, 3 insertions(+), 30 deletions(-)

diff --git a/arch/openrisc/include/asm/pgalloc.h 
b/arch/openrisc/include/asm/pgalloc.h
index da12a4c38c4b..88820299ecc4 100644
--- a/arch/openrisc/include/asm/pgalloc.h
+++ b/arch/openrisc/include/asm/pgalloc.h
@@ -20,6 +20,9 @@
 #include 
 #include 
 
+#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
+#include 
+
 extern int mem_init_done;
 
 #define pmd_populate_kernel(mm, pmd, pte) \
@@ -61,38 +64,8 @@ extern inline pgd_t *pgd_alloc(struct mm_struct *mm)
 }
 #endif
 
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-   free_page((unsigned long)pgd);
-}
-
 extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm)
-{
-   struct page *pte;
-   pte = alloc_pages(GFP_KERNEL, 0);
-   if (!pte)
-   return NULL;
-   clear_page(page_address(pte));
-   if (!pgtable_pte_page_ctor(pte)) {
-   __free_page(pte);
-   return NULL;
-   }
-   return pte;
-}
-
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
-{
-   free_page((unsigned long)pte);
-}
-
-static inline void pte_free(struct mm_struct *mm, struct page *pte)
-{
-   pgtable_pte_page_dtor(pte);
-   __free_page(pte);
-}
-
 #define __pte_free_tlb(tlb, pte, addr) \
 do {   \
pgtable_pte_page_dtor(pte); \
-- 
2.26.2


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


[PATCH 1/8] mm: remove unneeded includes of

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

In the most cases  header is required only for allocations
of page table memory. Most of the .c files that include that header do not
use symbols declared in  and do not require that header.

As for the other header files that used to include , it is
possible to move that include into the .c file that actually uses symbols
from  and drop the include from the header file.

The process was somewhat automated using

sed -i -E '/[<"]asm\/pgalloc\.h/d' \
$(grep -L -w -f /tmp/xx \
$(git grep -E -l '[<"]asm/pgalloc\.h'))

where /tmp/xx contains all the symbols defined in
arch/*/include/asm/pgalloc.h.

Signed-off-by: Mike Rapoport 
---
 arch/alpha/include/asm/tlbflush.h| 1 -
 arch/alpha/kernel/core_irongate.c| 1 -
 arch/alpha/kernel/core_marvel.c  | 1 -
 arch/alpha/kernel/core_titan.c   | 1 -
 arch/alpha/kernel/machvec_impl.h | 2 --
 arch/alpha/kernel/smp.c  | 1 -
 arch/alpha/mm/numa.c | 1 -
 arch/arc/mm/fault.c  | 1 -
 arch/arc/mm/init.c   | 1 -
 arch/arm/include/asm/tlb.h   | 1 -
 arch/arm/kernel/machine_kexec.c  | 1 -
 arch/arm/kernel/smp.c| 1 -
 arch/arm/kernel/suspend.c| 1 -
 arch/arm/mach-omap2/omap-mpuss-lowpower.c| 1 -
 arch/arm/mm/hugetlbpage.c| 1 -
 arch/arm/mm/mmu.c| 1 +
 arch/arm64/kernel/smp.c  | 1 -
 arch/arm64/mm/hugetlbpage.c  | 1 -
 arch/arm64/mm/ioremap.c  | 1 -
 arch/arm64/mm/mmu.c  | 1 +
 arch/csky/kernel/smp.c   | 1 -
 arch/ia64/include/asm/tlb.h  | 1 -
 arch/ia64/kernel/process.c   | 1 -
 arch/ia64/kernel/smp.c   | 1 -
 arch/ia64/kernel/smpboot.c   | 1 -
 arch/ia64/mm/contig.c| 1 -
 arch/ia64/mm/discontig.c | 1 -
 arch/ia64/mm/hugetlbpage.c   | 1 -
 arch/ia64/mm/tlb.c   | 1 -
 arch/m68k/include/asm/mmu_context.h  | 2 +-
 arch/m68k/kernel/dma.c   | 2 +-
 arch/m68k/kernel/traps.c | 3 +--
 arch/m68k/mm/cache.c | 2 +-
 arch/m68k/mm/fault.c | 1 -
 arch/m68k/mm/kmap.c  | 2 +-
 arch/m68k/mm/mcfmmu.c| 1 +
 arch/m68k/mm/memory.c| 1 -
 arch/m68k/sun3x/dvma.c   | 2 +-
 arch/microblaze/include/asm/tlbflush.h   | 1 -
 arch/microblaze/kernel/process.c | 1 -
 arch/microblaze/kernel/signal.c  | 1 -
 arch/mips/sgi-ip32/ip32-memory.c | 1 -
 arch/openrisc/include/asm/tlbflush.h | 1 -
 arch/openrisc/kernel/or32_ksyms.c| 1 -
 arch/parisc/include/asm/mmu_context.h| 1 -
 arch/parisc/kernel/cache.c   | 1 -
 arch/parisc/kernel/pci-dma.c | 1 -
 arch/parisc/kernel/process.c | 1 -
 arch/parisc/kernel/signal.c  | 1 -
 arch/parisc/kernel/smp.c | 1 -
 arch/parisc/mm/hugetlbpage.c | 1 -
 arch/parisc/mm/ioremap.c | 2 +-
 arch/powerpc/include/asm/tlb.h   | 1 -
 arch/powerpc/mm/book3s64/hash_hugetlbpage.c  | 1 -
 arch/powerpc/mm/book3s64/hash_pgtable.c  | 1 -
 arch/powerpc/mm/book3s64/hash_tlb.c  | 1 -
 arch/powerpc/mm/book3s64/radix_hugetlbpage.c | 1 -
 arch/powerpc/mm/init_32.c| 1 -
 arch/powerpc/mm/kasan/8xx.c  | 1 -
 arch/powerpc/mm/kasan/book3s_32.c| 1 -
 arch/powerpc/mm/mem.c| 1 -
 arch/powerpc/mm/nohash/40x.c | 1 -
 arch/powerpc/mm/nohash/8xx.c | 1 -
 arch/powerpc/mm/nohash/fsl_booke.c   | 1 -
 arch/powerpc/mm/nohash/kaslr_booke.c | 1 -
 arch/powerpc/mm/pgtable.c| 1 -
 arch/powerpc/mm/pgtable_64.c | 1 -
 arch/powerpc/mm/ptdump/hashpagetable.c   | 2 +-
 arch/powerpc/mm/ptdump/ptdump.c  | 1 -
 arch/powerpc/platforms/pseries/cmm.c | 1 -
 arch/riscv/mm/fault.c| 1 -
 arch/s390/include/asm/tlb.h  | 1 -
 arch/s390/include/asm/tlbflush.h | 1 -
 arch/s390/kernel/machine_kexec.c | 1 -
 arch/s390/kernel/ptrace.c| 1 -
 arch/s390/kvm/diag.c | 1 -
 arch/s390/kvm/priv.c | 1 -
 arch/s390/kvm/pv.c   | 1 -
 arch/s390/mm/cmm.c   | 1 -
 arch/s390/mm/mmap.c  | 1 -
 arch/s390/mm/pgtable.c   | 1 -
 arch/sh/kernel/idle.c| 1 -
 

[PATCH 0/8] mm: cleanup usage of

2020-06-27 Thread Mike Rapoport
From: Mike Rapoport 

Hi,

Most architectures have very similar versions of pXd_alloc_one() and
pXd_free_one() for intermediate levels of page table. 
These patches add generic versions of these functions in
 and enable use of the generic functions where
appropriate.

In addition, functions declared and defined in  headers
are used mostly by core mm and early mm initialization in arch and there is
no actual reason to have the  included all over the place.
The first patch in this series removes unneeded includes of 

In the end it didn't work out as neatly as I hoped and moving
pXd_alloc_track() definitions to  would require
unnecessary changes to arches that have custom page table allocations, so
I've decided to move lib/ioremap.c to mm/ and make pgalloc-track.h local to
mm/.

Joerg Roedel (1):
  mm: move p?d_alloc_track to separate header file

Mike Rapoport (7):
  mm: remove unneeded includes of 
  opeinrisc: switch to generic version of pte allocation
  xtensa: switch to generic version of pte allocation
  asm-generic: pgalloc: provide generic pmd_alloc_one() and pmd_free_one()
  asm-generic: pgalloc: provide generic pud_alloc_one() and pud_free_one()
  asm-generic: pgalloc: provide generic pgd_free()
  mm: move lib/ioremap.c to mm/

 arch/alpha/include/asm/pgalloc.h | 21 +
 arch/alpha/include/asm/tlbflush.h|  1 -
 arch/alpha/kernel/core_irongate.c|  1 -
 arch/alpha/kernel/core_marvel.c  |  1 -
 arch/alpha/kernel/core_titan.c   |  1 -
 arch/alpha/kernel/machvec_impl.h |  2 -
 arch/alpha/kernel/smp.c  |  1 -
 arch/alpha/mm/numa.c |  1 -
 arch/arc/mm/fault.c  |  1 -
 arch/arc/mm/init.c   |  1 -
 arch/arm/include/asm/pgalloc.h   | 12 +--
 arch/arm/include/asm/tlb.h   |  1 -
 arch/arm/kernel/machine_kexec.c  |  1 -
 arch/arm/kernel/smp.c|  1 -
 arch/arm/kernel/suspend.c|  1 -
 arch/arm/mach-omap2/omap-mpuss-lowpower.c|  1 -
 arch/arm/mm/hugetlbpage.c|  1 -
 arch/arm/mm/mmu.c|  1 +
 arch/arm64/include/asm/pgalloc.h | 39 +-
 arch/arm64/kernel/smp.c  |  1 -
 arch/arm64/mm/hugetlbpage.c  |  1 -
 arch/arm64/mm/ioremap.c  |  1 -
 arch/arm64/mm/mmu.c  |  1 +
 arch/csky/include/asm/pgalloc.h  |  7 +-
 arch/csky/kernel/smp.c   |  1 -
 arch/hexagon/include/asm/pgalloc.h   |  7 +-
 arch/ia64/include/asm/pgalloc.h  | 24 --
 arch/ia64/include/asm/tlb.h  |  1 -
 arch/ia64/kernel/process.c   |  1 -
 arch/ia64/kernel/smp.c   |  1 -
 arch/ia64/kernel/smpboot.c   |  1 -
 arch/ia64/mm/contig.c|  1 -
 arch/ia64/mm/discontig.c |  1 -
 arch/ia64/mm/hugetlbpage.c   |  1 -
 arch/ia64/mm/tlb.c   |  1 -
 arch/m68k/include/asm/mmu_context.h  |  2 +-
 arch/m68k/include/asm/sun3_pgalloc.h |  7 +-
 arch/m68k/kernel/dma.c   |  2 +-
 arch/m68k/kernel/traps.c |  3 +-
 arch/m68k/mm/cache.c |  2 +-
 arch/m68k/mm/fault.c |  1 -
 arch/m68k/mm/kmap.c  |  2 +-
 arch/m68k/mm/mcfmmu.c|  1 +
 arch/m68k/mm/memory.c|  1 -
 arch/m68k/sun3x/dvma.c   |  2 +-
 arch/microblaze/include/asm/pgalloc.h|  6 --
 arch/microblaze/include/asm/tlbflush.h   |  1 -
 arch/microblaze/kernel/process.c |  1 -
 arch/microblaze/kernel/signal.c  |  1 -
 arch/mips/include/asm/pgalloc.h  | 19 +
 arch/mips/sgi-ip32/ip32-memory.c |  1 -
 arch/nds32/mm/mm-nds32.c |  2 +
 arch/nios2/include/asm/pgalloc.h |  7 +-
 arch/openrisc/include/asm/pgalloc.h  | 33 +---
 arch/openrisc/include/asm/tlbflush.h |  1 -
 arch/openrisc/kernel/or32_ksyms.c|  1 -
 arch/parisc/include/asm/mmu_context.h|  1 -
 arch/parisc/include/asm/pgalloc.h| 12 +--
 arch/parisc/kernel/cache.c   |  1 -
 arch/parisc/kernel/pci-dma.c |  1 -
 arch/parisc/kernel/process.c |  1 -
 arch/parisc/kernel/signal.c  |  1 -
 arch/parisc/kernel/smp.c |  1 -
 arch/parisc/mm/hugetlbpage.c |  1 -
 arch/parisc/mm/ioremap.c |  2 +-
 arch/powerpc/include/asm/tlb.h   |  1 -
 arch/powerpc/mm/book3s64/hash_hugetlbpage.c  |  1 -
 arch/powerpc/mm/book3s64/hash_pgtable.c  |  1 -
 arch/powerpc/mm/book3s64/hash_tlb.c  |  1 -
 

Re: [PATCH V3 0/4] mm/debug_vm_pgtable: Add some more tests

2020-06-27 Thread Christophe Leroy



Le 24/06/2020 à 05:13, Anshuman Khandual a écrit :



On 06/15/2020 09:07 AM, Anshuman Khandual wrote:

This series adds some more arch page table helper validation tests which
are related to core and advanced memory functions. This also creates a
documentation, enlisting expected semantics for all page table helpers as
suggested by Mike Rapoport previously (https://lkml.org/lkml/2020/1/30/40).

There are many TRANSPARENT_HUGEPAGE and ARCH_HAS_TRANSPARENT_HUGEPAGE_PUD
ifdefs scattered across the test. But consolidating all the fallback stubs
is not very straight forward because ARCH_HAS_TRANSPARENT_HUGEPAGE_PUD is
not explicitly dependent on ARCH_HAS_TRANSPARENT_HUGEPAGE.

Tested on arm64, x86 platforms but only build tested on all other enabled
platforms through ARCH_HAS_DEBUG_VM_PGTABLE i.e powerpc, arc, s390. The
following failure on arm64 still exists which was mentioned previously. It
will be fixed with the upcoming THP migration on arm64 enablement series.

WARNING  mm/debug_vm_pgtable.c:860 debug_vm_pgtable+0x940/0xa54
WARN_ON(!pmd_present(pmd_mkinvalid(pmd_mkhuge(pmd

This series is based on v5.8-rc1.

Changes in V3:

- Replaced HAVE_ARCH_SOFT_DIRTY with MEM_SOFT_DIRTY
- Added HAVE_ARCH_HUGE_VMAP checks in pxx_huge_tests() per Gerald
- Updated documentation for pmd_thp_tests() per Zi Yan
- Replaced READ_ONCE() with huge_ptep_get() per Gerald
- Added pte_mkhuge() and masking with PMD_MASK per Gerald
- Replaced pte_same() with holding pfn check in pxx_swap_tests()
- Added documentation for all (#ifdef #else #endif) per Gerald
- Updated pmd_protnone_tests() per Gerald
- Updated HugeTLB PTE creation in hugetlb_advanced_tests() per Gerald
- Replaced [pmd|pud]_mknotpresent() with [pmd|pud]_mkinvalid()
- Added has_transparent_hugepage() check for PMD and PUD tests
- Added a patch which debug prints all individual tests being executed
- Updated documentation for renamed [pmd|pud]_mkinvalid() helpers


Hello Gerald/Christophe/Vineet,

It would be really great if you could give this series a quick test
on s390/ppc/arc platforms respectively. Thank you.



Running ok on powerpc 8xx after fixing build failures.

Christophe

___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


Re: [PATCH V3 2/4] mm/debug_vm_pgtable: Add tests validating advanced arch page table helpers

2020-06-27 Thread Christophe Leroy



Le 15/06/2020 à 05:37, Anshuman Khandual a écrit :

This adds new tests validating for these following arch advanced page table
helpers. These tests create and test specific mapping types at various page
table levels.

1. pxxp_set_wrprotect()
2. pxxp_get_and_clear()
3. pxxp_set_access_flags()
4. pxxp_get_and_clear_full()
5. pxxp_test_and_clear_young()
6. pxx_leaf()
7. pxx_set_huge()
8. pxx_(clear|mk)_savedwrite()
9. huge_pxxp_xxx()

Cc: Andrew Morton 
Cc: Mike Rapoport 
Cc: Vineet Gupta 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Heiko Carstens 
Cc: Vasily Gorbik 
Cc: Christian Borntraeger 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: "H. Peter Anvin" 
Cc: Kirill A. Shutemov 
Cc: Paul Walmsley 
Cc: Palmer Dabbelt 
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linuxppc-...@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
Cc: linux-ri...@lists.infradead.org
Cc: x...@kernel.org
Cc: linux...@kvack.org
Cc: linux-a...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Suggested-by: Catalin Marinas 
Signed-off-by: Anshuman Khandual 
---
  mm/debug_vm_pgtable.c | 306 ++
  1 file changed, 306 insertions(+)

diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index ffa163d4c63c..e3f9f8317a98 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -21,6 +21,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -28,6 +29,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #define VMFLAGS	(VM_READ|VM_WRITE|VM_EXEC)
  
@@ -55,6 +57,54 @@ static void __init pte_basic_tests(unsigned long pfn, pgprot_t prot)

WARN_ON(pte_write(pte_wrprotect(pte_mkwrite(pte;
  }
  
+static void __init pte_advanced_tests(struct mm_struct *mm,

+   struct vm_area_struct *vma, pte_t *ptep,
+   unsigned long pfn, unsigned long vaddr, pgprot_t prot)


Align args properly.


+{
+   pte_t pte = pfn_pte(pfn, prot);
+
+   pte = pfn_pte(pfn, prot);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_set_wrprotect(mm, vaddr, ptep);
+   pte = READ_ONCE(*ptep);
+   WARN_ON(pte_write(pte));
+
+   pte = pfn_pte(pfn, prot);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_get_and_clear(mm, vaddr, ptep);
+   pte = READ_ONCE(*ptep);
+   WARN_ON(!pte_none(pte));
+
+   pte = pfn_pte(pfn, prot);
+   pte = pte_wrprotect(pte);
+   pte = pte_mkclean(pte);
+   set_pte_at(mm, vaddr, ptep, pte);
+   pte = pte_mkwrite(pte);
+   pte = pte_mkdirty(pte);
+   ptep_set_access_flags(vma, vaddr, ptep, pte, 1);
+   pte = READ_ONCE(*ptep);
+   WARN_ON(!(pte_write(pte) && pte_dirty(pte)));
+
+   pte = pfn_pte(pfn, prot);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_get_and_clear_full(mm, vaddr, ptep, 1);
+   pte = READ_ONCE(*ptep);
+   WARN_ON(!pte_none(pte));
+
+   pte = pte_mkyoung(pte);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_test_and_clear_young(vma, vaddr, ptep);
+   pte = READ_ONCE(*ptep);
+   WARN_ON(pte_young(pte));
+}
+
+static void __init pte_savedwrite_tests(unsigned long pfn, pgprot_t prot)
+{
+   pte_t pte = pfn_pte(pfn, prot);
+
+   WARN_ON(!pte_savedwrite(pte_mk_savedwrite(pte_clear_savedwrite(pte;
+   WARN_ON(pte_savedwrite(pte_clear_savedwrite(pte_mk_savedwrite(pte;
+}
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  static void __init pmd_basic_tests(unsigned long pfn, pgprot_t prot)
  {
@@ -77,6 +127,89 @@ static void __init pmd_basic_tests(unsigned long pfn, 
pgprot_t prot)
WARN_ON(!pmd_bad(pmd_mkhuge(pmd)));
  }
  
+static void __init pmd_advanced_tests(struct mm_struct *mm,

+   struct vm_area_struct *vma, pmd_t *pmdp,
+   unsigned long pfn, unsigned long vaddr, pgprot_t prot)


Align args properly


+{
+   pmd_t pmd = pfn_pmd(pfn, prot);
+
+   if (!has_transparent_hugepage())
+   return;
+
+   /* Align the address wrt HPAGE_PMD_SIZE */
+   vaddr = (vaddr & HPAGE_PMD_MASK) + HPAGE_PMD_SIZE;
+
+   pmd = pfn_pmd(pfn, prot);
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+   pmdp_set_wrprotect(mm, vaddr, pmdp);
+   pmd = READ_ONCE(*pmdp);
+   WARN_ON(pmd_write(pmd));
+
+   pmd = pfn_pmd(pfn, prot);
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+   pmdp_huge_get_and_clear(mm, vaddr, pmdp);
+   pmd = READ_ONCE(*pmdp);
+   WARN_ON(!pmd_none(pmd));
+
+   pmd = pfn_pmd(pfn, prot);
+   pmd = pmd_wrprotect(pmd);
+   pmd = pmd_mkclean(pmd);
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+   pmd = pmd_mkwrite(pmd);
+   pmd = pmd_mkdirty(pmd);
+   pmdp_set_access_flags(vma, vaddr, pmdp, pmd, 1);
+   pmd = READ_ONCE(*pmdp);
+   WARN_ON(!(pmd_write(pmd) && pmd_dirty(pmd)));
+
+   pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
+   set_pmd_at(mm, vaddr, pmdp, pmd);

Re: [PATCH V3 2/4] mm/debug_vm_pgtable: Add tests validating advanced arch page table helpers

2020-06-27 Thread Christophe Leroy



Le 15/06/2020 à 05:37, Anshuman Khandual a écrit :

This adds new tests validating for these following arch advanced page table
helpers. These tests create and test specific mapping types at various page
table levels.

1. pxxp_set_wrprotect()
2. pxxp_get_and_clear()
3. pxxp_set_access_flags()
4. pxxp_get_and_clear_full()
5. pxxp_test_and_clear_young()
6. pxx_leaf()
7. pxx_set_huge()
8. pxx_(clear|mk)_savedwrite()
9. huge_pxxp_xxx()

Cc: Andrew Morton 
Cc: Mike Rapoport 
Cc: Vineet Gupta 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Heiko Carstens 
Cc: Vasily Gorbik 
Cc: Christian Borntraeger 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: "H. Peter Anvin" 
Cc: Kirill A. Shutemov 
Cc: Paul Walmsley 
Cc: Palmer Dabbelt 
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linuxppc-...@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
Cc: linux-ri...@lists.infradead.org
Cc: x...@kernel.org
Cc: linux...@kvack.org
Cc: linux-a...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Suggested-by: Catalin Marinas 
Signed-off-by: Anshuman Khandual 
---
  mm/debug_vm_pgtable.c | 306 ++
  1 file changed, 306 insertions(+)

diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index ffa163d4c63c..e3f9f8317a98 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -21,6 +21,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -28,6 +29,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #define VMFLAGS	(VM_READ|VM_WRITE|VM_EXEC)
  
@@ -55,6 +57,54 @@ static void __init pte_basic_tests(unsigned long pfn, pgprot_t prot)

WARN_ON(pte_write(pte_wrprotect(pte_mkwrite(pte;
  }
  
+static void __init pte_advanced_tests(struct mm_struct *mm,

+   struct vm_area_struct *vma, pte_t *ptep,
+   unsigned long pfn, unsigned long vaddr, pgprot_t prot)
+{
+   pte_t pte = pfn_pte(pfn, prot);
+
+   pte = pfn_pte(pfn, prot);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_set_wrprotect(mm, vaddr, ptep);
+   pte = READ_ONCE(*ptep);


same


+   WARN_ON(pte_write(pte));
+
+   pte = pfn_pte(pfn, prot);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_get_and_clear(mm, vaddr, ptep);
+   pte = READ_ONCE(*ptep);


same


+   WARN_ON(!pte_none(pte));
+
+   pte = pfn_pte(pfn, prot);
+   pte = pte_wrprotect(pte);
+   pte = pte_mkclean(pte);
+   set_pte_at(mm, vaddr, ptep, pte);
+   pte = pte_mkwrite(pte);
+   pte = pte_mkdirty(pte);
+   ptep_set_access_flags(vma, vaddr, ptep, pte, 1);
+   pte = READ_ONCE(*ptep);


same


+   WARN_ON(!(pte_write(pte) && pte_dirty(pte)));
+
+   pte = pfn_pte(pfn, prot);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_get_and_clear_full(mm, vaddr, ptep, 1);
+   pte = READ_ONCE(*ptep);


same


+   WARN_ON(!pte_none(pte));
+
+   pte = pte_mkyoung(pte);
+   set_pte_at(mm, vaddr, ptep, pte);
+   ptep_test_and_clear_young(vma, vaddr, ptep);
+   pte = READ_ONCE(*ptep);


same


+   WARN_ON(pte_young(pte));
+}
+
+static void __init pte_savedwrite_tests(unsigned long pfn, pgprot_t prot)
+{
+   pte_t pte = pfn_pte(pfn, prot);
+
+   WARN_ON(!pte_savedwrite(pte_mk_savedwrite(pte_clear_savedwrite(pte;
+   WARN_ON(pte_savedwrite(pte_clear_savedwrite(pte_mk_savedwrite(pte;
+}
  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  static void __init pmd_basic_tests(unsigned long pfn, pgprot_t prot)
  {
@@ -77,6 +127,89 @@ static void __init pmd_basic_tests(unsigned long pfn, 
pgprot_t prot)
WARN_ON(!pmd_bad(pmd_mkhuge(pmd)));
  }
  
+static void __init pmd_advanced_tests(struct mm_struct *mm,

+   struct vm_area_struct *vma, pmd_t *pmdp,
+   unsigned long pfn, unsigned long vaddr, pgprot_t prot)
+{
+   pmd_t pmd = pfn_pmd(pfn, prot);
+
+   if (!has_transparent_hugepage())
+   return;
+
+   /* Align the address wrt HPAGE_PMD_SIZE */
+   vaddr = (vaddr & HPAGE_PMD_MASK) + HPAGE_PMD_SIZE;
+
+   pmd = pfn_pmd(pfn, prot);
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+   pmdp_set_wrprotect(mm, vaddr, pmdp);
+   pmd = READ_ONCE(*pmdp);
+   WARN_ON(pmd_write(pmd));
+
+   pmd = pfn_pmd(pfn, prot);
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+   pmdp_huge_get_and_clear(mm, vaddr, pmdp);
+   pmd = READ_ONCE(*pmdp);
+   WARN_ON(!pmd_none(pmd));
+
+   pmd = pfn_pmd(pfn, prot);
+   pmd = pmd_wrprotect(pmd);
+   pmd = pmd_mkclean(pmd);
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+   pmd = pmd_mkwrite(pmd);
+   pmd = pmd_mkdirty(pmd);
+   pmdp_set_access_flags(vma, vaddr, pmdp, pmd, 1);
+   pmd = READ_ONCE(*pmdp);
+   WARN_ON(!(pmd_write(pmd) && pmd_dirty(pmd)));
+
+   pmd = pmd_mkhuge(pfn_pmd(pfn, prot));
+   set_pmd_at(mm, vaddr, pmdp, pmd);
+