2019-03-20 10:11:18

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 00/27] Reduce ifdef mess in hugetlbpage.c and slice.c

The main purpose of this series is to reduce the amount of #ifdefs in
hugetlbpage.c and slice.c

At the same time, it does some cleanup by reducing the number of BUG_ON()
and dropping unused functions.

It also removes 64k pages related code in nohash/64 as 64k pages are
can only by selected on book3s/64

Christophe Leroy (27):
powerpc/mm: Don't BUG() in hugepd_page()
powerpc/mm: don't BUG in add_huge_page_size()
powerpc/mm: don't BUG() in slice_mask_for_size()
powerpc/book3e: drop mmu_get_tsize()
powerpc/mm: drop slice_set_user_psize()
powerpc/64: only book3s/64 supports CONFIG_PPC_64K_PAGES
powerpc/book3e: hugetlbpage is only for CONFIG_PPC_FSL_BOOK3E
powerpc/mm: move __find_linux_pte() out of hugetlbpage.c
powerpc/mm: make hugetlbpage.c depend on CONFIG_HUGETLB_PAGE
powerpc/mm: make gup_hugepte() static
powerpc/mm: split asm/hugetlb.h into dedicated subarch files
powerpc/mm: add a helper to populate hugepd
powerpc/mm: define get_slice_psize() all the time
powerpc/mm: no slice for nohash/64
powerpc/mm: cleanup ifdef mess in add_huge_page_size()
powerpc/mm: move hugetlb_disabled into asm/hugetlb.h
powerpc/mm: cleanup HPAGE_SHIFT setup
powerpc/mm: cleanup remaining ifdef mess in hugetlbpage.c
powerpc/mm: drop slice DEBUG
powerpc/mm: remove unnecessary #ifdef CONFIG_PPC64
powerpc/mm: hand a context_t over to slice_mask_for_size() instead of
mm_struct
powerpc/mm: move slice_mask_for_size() into mmu.h
powerpc/mm: remove a couple of #ifdef CONFIG_PPC_64K_PAGES in
mm/slice.c
powerpc: define subarch SLB_ADDR_LIMIT_DEFAULT
powerpc/mm: flatten function __find_linux_pte()
powerpc/mm: flatten function __find_linux_pte() step 2
powerpc/mm: flatten function __find_linux_pte() step 3

arch/powerpc/Kconfig | 3 +-
arch/powerpc/include/asm/book3s/64/hugetlb.h | 73 +++++++
arch/powerpc/include/asm/book3s/64/mmu.h | 22 +-
arch/powerpc/include/asm/book3s/64/slice.h | 7 +-
arch/powerpc/include/asm/hugetlb.h | 87 +-------
arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 45 +++++
arch/powerpc/include/asm/nohash/32/mmu-8xx.h | 18 ++
arch/powerpc/include/asm/nohash/32/slice.h | 2 +
arch/powerpc/include/asm/nohash/64/pgalloc.h | 3 -
arch/powerpc/include/asm/nohash/64/pgtable.h | 4 -
arch/powerpc/include/asm/nohash/64/slice.h | 12 --
arch/powerpc/include/asm/nohash/hugetlb-book3e.h | 45 +++++
arch/powerpc/include/asm/nohash/pte-book3e.h | 5 -
arch/powerpc/include/asm/page.h | 12 +-
arch/powerpc/include/asm/pgtable-be-types.h | 7 +-
arch/powerpc/include/asm/pgtable-types.h | 7 +-
arch/powerpc/include/asm/pgtable.h | 3 -
arch/powerpc/include/asm/slice.h | 8 +-
arch/powerpc/include/asm/task_size_64.h | 2 +-
arch/powerpc/kernel/fadump.c | 1 +
arch/powerpc/kernel/setup-common.c | 8 +-
arch/powerpc/mm/Makefile | 4 +-
arch/powerpc/mm/hash_utils_64.c | 1 +
arch/powerpc/mm/hugetlbpage-book3e.c | 52 ++---
arch/powerpc/mm/hugetlbpage-hash64.c | 16 ++
arch/powerpc/mm/hugetlbpage.c | 245 ++++-------------------
arch/powerpc/mm/pgtable.c | 114 +++++++++++
arch/powerpc/mm/slice.c | 132 ++----------
arch/powerpc/mm/tlb_low_64e.S | 31 ---
arch/powerpc/mm/tlb_nohash.c | 13 --
arch/powerpc/platforms/Kconfig.cputype | 4 +
31 files changed, 438 insertions(+), 548 deletions(-)
create mode 100644 arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
delete mode 100644 arch/powerpc/include/asm/nohash/64/slice.h
create mode 100644 arch/powerpc/include/asm/nohash/hugetlb-book3e.h

--
2.13.3



2019-03-20 10:07:40

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 02/27] powerpc/mm: don't BUG in add_huge_page_size()

No reason to BUG() in add_huge_page_size(). Just WARN and
reject the add.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/hugetlbpage.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 9e732bb2c84a..cf2978e235f3 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -634,7 +634,8 @@ static int __init add_huge_page_size(unsigned long long size)
}
#endif

- BUG_ON(mmu_psize_defs[mmu_psize].shift != shift);
+ if (WARN_ON(mmu_psize_defs[mmu_psize].shift != shift))
+ return -EINVAL;

/* Return if huge page size has already been setup */
if (size_to_hstate(size))
--
2.13.3


2019-03-20 10:07:44

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 04/27] powerpc/book3e: drop mmu_get_tsize()

This function is not used anymore, drop it.

Fixes: b42279f0165c ("powerpc/mm/nohash: MM_SLICE is only used by book3s 64")
Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/hugetlbpage-book3e.c | 5 -----
1 file changed, 5 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
index f84ec46cdb26..c911fe9bfa0e 100644
--- a/arch/powerpc/mm/hugetlbpage-book3e.c
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -49,11 +49,6 @@ static inline int tlb1_next(void)
#endif /* !PPC64 */
#endif /* FSL */

-static inline int mmu_get_tsize(int psize)
-{
- return mmu_psize_defs[psize].enc;
-}
-
#if defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_PPC64)
#include <asm/paca.h>

--
2.13.3


2019-03-20 10:08:06

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 17/27] powerpc/mm: cleanup HPAGE_SHIFT setup

Only book3s/64 may select default among several HPAGE_SHIFT at runtime.
8xx always defines 512K pages as default
FSL_BOOK3E always defines 4M pages as default

This patch limits HUGETLB_PAGE_SIZE_VARIABLE to book3s/64
moves the definitions in subarches files.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/Kconfig | 2 +-
arch/powerpc/include/asm/hugetlb.h | 2 ++
arch/powerpc/include/asm/page.h | 11 ++++++++---
arch/powerpc/mm/hugetlbpage-hash64.c | 16 ++++++++++++++++
arch/powerpc/mm/hugetlbpage.c | 23 +++--------------------
5 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5d8e692d6470..7815eb0cc2a5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -390,7 +390,7 @@ source "kernel/Kconfig.hz"

config HUGETLB_PAGE_SIZE_VARIABLE
bool
- depends on HUGETLB_PAGE
+ depends on HUGETLB_PAGE && PPC_BOOK3S_64
default y

config MATH_EMULATION
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 84598c6b0959..20a101046cff 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -15,6 +15,8 @@

extern bool hugetlb_disabled;

+void hugetlbpage_init_default(void);
+
void flush_dcache_icache_hugepage(struct page *page);

int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 0c11a7513919..eef10fe0e06f 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -28,10 +28,15 @@
#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)

#ifndef __ASSEMBLY__
-#ifdef CONFIG_HUGETLB_PAGE
-extern unsigned int HPAGE_SHIFT;
-#else
+#ifndef CONFIG_HUGETLB_PAGE
#define HPAGE_SHIFT PAGE_SHIFT
+#elif defined(CONFIG_PPC_BOOK3S_64)
+extern unsigned int hpage_shift;
+#define HPAGE_SHIFT hpage_shift
+#elif defined(CONFIG_PPC_8xx)
+#define HPAGE_SHIFT 19 /* 512k pages */
+#elif defined(CONFIG_PPC_FSL_BOOK3E)
+#define HPAGE_SHIFT 22 /* 4M pages */
#endif
#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index b0d9209d9a86..7a58204c3688 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -15,6 +15,9 @@
#include <asm/cacheflush.h>
#include <asm/machdep.h>

+unsigned int hpage_shift;
+EXPORT_SYMBOL(hpage_shift);
+
extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
unsigned long pa, unsigned long rlags,
unsigned long vflags, int psize, int ssize);
@@ -145,3 +148,16 @@ void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr
old_pte, pte);
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
}
+
+void hugetlbpage_init_default(void)
+{
+ /* Set default large page size. Currently, we pick 16M or 1M
+ * depending on what is available
+ */
+ if (mmu_psize_defs[MMU_PAGE_16M].shift)
+ hpage_shift = mmu_psize_defs[MMU_PAGE_16M].shift;
+ else if (mmu_psize_defs[MMU_PAGE_1M].shift)
+ hpage_shift = mmu_psize_defs[MMU_PAGE_1M].shift;
+ else if (mmu_psize_defs[MMU_PAGE_2M].shift)
+ hpage_shift = mmu_psize_defs[MMU_PAGE_2M].shift;
+}
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 3b449c9d4e47..dd62006e1243 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -28,9 +28,6 @@

bool hugetlb_disabled = false;

-unsigned int HPAGE_SHIFT;
-EXPORT_SYMBOL(HPAGE_SHIFT);
-
#define hugepd_none(hpd) (hpd_val(hpd) == 0)

#define PTE_T_ORDER (__builtin_ffs(sizeof(pte_t)) - __builtin_ffs(sizeof(void *)))
@@ -646,23 +643,9 @@ static int __init hugetlbpage_init(void)
#endif
}

-#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx)
- /* Default hpage size = 4M on FSL_BOOK3E and 512k on 8xx */
- if (mmu_psize_defs[MMU_PAGE_4M].shift)
- HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift;
- else if (mmu_psize_defs[MMU_PAGE_512K].shift)
- HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_512K].shift;
-#else
- /* Set default large page size. Currently, we pick 16M or 1M
- * depending on what is available
- */
- if (mmu_psize_defs[MMU_PAGE_16M].shift)
- HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_16M].shift;
- else if (mmu_psize_defs[MMU_PAGE_1M].shift)
- HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_1M].shift;
- else if (mmu_psize_defs[MMU_PAGE_2M].shift)
- HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_2M].shift;
-#endif
+ if (IS_ENABLED(HUGETLB_PAGE_SIZE_VARIABLE))
+ hugetlbpage_init_default();
+
return 0;
}

--
2.13.3


2019-03-20 10:08:10

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 18/27] powerpc/mm: cleanup remaining ifdef mess in hugetlbpage.c

Only 3 subarches support huge pages. So when it either 2 of them, it
is not the third one.

And mmu_has_feature() is known by all subarches so IS_ENABLED() can
be used instead of #ifdef

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/hugetlbpage.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index dd62006e1243..a463ebf276b6 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -226,7 +226,7 @@ int __init alloc_bootmem_huge_page(struct hstate *h)
return __alloc_bootmem_huge_page(h);
}

-#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx)
+#ifndef CONFIG_PPC_BOOK3S_64
#define HUGEPD_FREELIST_SIZE \
((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t))

@@ -596,10 +596,10 @@ static int __init hugetlbpage_init(void)
return 0;
}

-#if !defined(CONFIG_PPC_FSL_BOOK3E) && !defined(CONFIG_PPC_8xx)
- if (!radix_enabled() && !mmu_has_feature(MMU_FTR_16M_PAGE))
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled() &&
+ !mmu_has_feature(MMU_FTR_16M_PAGE))
return -ENODEV;
-#endif
+
for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
unsigned shift;
unsigned pdshift;
@@ -637,10 +637,8 @@ static int __init hugetlbpage_init(void)
pgtable_cache_add(PTE_INDEX_SIZE);
else if (pdshift > shift)
pgtable_cache_add(pdshift - shift);
-#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx)
- else
+ else if (IS_ENABLED(CONFIG_PPC_FSL_BOOK3E) || IS_ENABLED(CONFIG_PPC_8xx))
pgtable_cache_add(PTE_T_ORDER);
-#endif
}

if (IS_ENABLED(HUGETLB_PAGE_SIZE_VARIABLE))
--
2.13.3


2019-03-20 10:08:23

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 26/27] powerpc/mm: flatten function __find_linux_pte() step 2

__find_linux_pte() is full of if/else which is hard to
follow allthough the handling is pretty simple.

Previous patch left { } blocks. This patch removes the first one
by shifting its content to the left.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/pgtable.c | 62 +++++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index d332abeedf0a..c1c6d0b79baa 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -369,39 +369,37 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
hpdp = (hugepd_t *)&pud;
goto out_huge;
}
- {
- pdshift = PMD_SHIFT;
- pmdp = pmd_offset(&pud, ea);
- pmd = READ_ONCE(*pmdp);
- /*
- * A hugepage collapse is captured by pmd_none, because
- * it mark the pmd none and do a hpte invalidate.
- */
- if (pmd_none(pmd))
- return NULL;
-
- if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
- if (is_thp)
- *is_thp = true;
- ret_pte = (pte_t *) pmdp;
- goto out;
- }
- /*
- * pmd_large check below will handle the swap pmd pte
- * we need to do both the check because they are config
- * dependent.
- */
- if (pmd_huge(pmd) || pmd_large(pmd)) {
- ret_pte = (pte_t *) pmdp;
- goto out;
- }
- if (is_hugepd(__hugepd(pmd_val(pmd)))) {
- hpdp = (hugepd_t *)&pmd;
- goto out_huge;
- }
-
- return pte_offset_kernel(&pmd, ea);
+ pdshift = PMD_SHIFT;
+ pmdp = pmd_offset(&pud, ea);
+ pmd = READ_ONCE(*pmdp);
+ /*
+ * A hugepage collapse is captured by pmd_none, because
+ * it mark the pmd none and do a hpte invalidate.
+ */
+ if (pmd_none(pmd))
+ return NULL;
+
+ if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
+ if (is_thp)
+ *is_thp = true;
+ ret_pte = (pte_t *)pmdp;
+ goto out;
+ }
+ /*
+ * pmd_large check below will handle the swap pmd pte
+ * we need to do both the check because they are config
+ * dependent.
+ */
+ if (pmd_huge(pmd) || pmd_large(pmd)) {
+ ret_pte = (pte_t *)pmdp;
+ goto out;
}
+ if (is_hugepd(__hugepd(pmd_val(pmd)))) {
+ hpdp = (hugepd_t *)&pmd;
+ goto out_huge;
+ }
+
+ return pte_offset_kernel(&pmd, ea);
}
out_huge:
if (!hpdp)
--
2.13.3


2019-03-20 10:08:29

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 25/27] powerpc/mm: flatten function __find_linux_pte()

__find_linux_pte() is full of if/else which is hard to
follow allthough the handling is pretty simple.

This patch flattens the function by getting rid of as much if/else
as possible. In order to ease the review, this is done in two steps.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/pgtable.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 9f4ccd15849f..d332abeedf0a 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -339,12 +339,16 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
*/
if (pgd_none(pgd))
return NULL;
- else if (pgd_huge(pgd)) {
- ret_pte = (pte_t *) pgdp;
+
+ if (pgd_huge(pgd)) {
+ ret_pte = (pte_t *)pgdp;
goto out;
- } else if (is_hugepd(__hugepd(pgd_val(pgd))))
+ }
+ if (is_hugepd(__hugepd(pgd_val(pgd)))) {
hpdp = (hugepd_t *)&pgd;
- else {
+ goto out_huge;
+ }
+ {
/*
* Even if we end up with an unmap, the pgtable will not
* be freed, because we do an rcu free and here we are
@@ -356,12 +360,16 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,

if (pud_none(pud))
return NULL;
- else if (pud_huge(pud)) {
+
+ if (pud_huge(pud)) {
ret_pte = (pte_t *) pudp;
goto out;
- } else if (is_hugepd(__hugepd(pud_val(pud))))
+ }
+ if (is_hugepd(__hugepd(pud_val(pud)))) {
hpdp = (hugepd_t *)&pud;
- else {
+ goto out_huge;
+ }
+ {
pdshift = PMD_SHIFT;
pmdp = pmd_offset(&pud, ea);
pmd = READ_ONCE(*pmdp);
@@ -386,12 +394,16 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
if (pmd_huge(pmd) || pmd_large(pmd)) {
ret_pte = (pte_t *) pmdp;
goto out;
- } else if (is_hugepd(__hugepd(pmd_val(pmd))))
+ }
+ if (is_hugepd(__hugepd(pmd_val(pmd)))) {
hpdp = (hugepd_t *)&pmd;
- else
- return pte_offset_kernel(&pmd, ea);
+ goto out_huge;
+ }
+
+ return pte_offset_kernel(&pmd, ea);
}
}
+out_huge:
if (!hpdp)
return NULL;

--
2.13.3


2019-03-20 10:08:36

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 27/27] powerpc/mm: flatten function __find_linux_pte() step 3

__find_linux_pte() is full of if/else which is hard to
follow allthough the handling is pretty simple.

Previous patches left a { } block. This patch removes it.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/pgtable.c | 98 +++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 49 deletions(-)

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index c1c6d0b79baa..db4a6253df92 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -348,59 +348,59 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
hpdp = (hugepd_t *)&pgd;
goto out_huge;
}
- {
- /*
- * Even if we end up with an unmap, the pgtable will not
- * be freed, because we do an rcu free and here we are
- * irq disabled
- */
- pdshift = PUD_SHIFT;
- pudp = pud_offset(&pgd, ea);
- pud = READ_ONCE(*pudp);

- if (pud_none(pud))
- return NULL;
+ /*
+ * Even if we end up with an unmap, the pgtable will not
+ * be freed, because we do an rcu free and here we are
+ * irq disabled
+ */
+ pdshift = PUD_SHIFT;
+ pudp = pud_offset(&pgd, ea);
+ pud = READ_ONCE(*pudp);

- if (pud_huge(pud)) {
- ret_pte = (pte_t *) pudp;
- goto out;
- }
- if (is_hugepd(__hugepd(pud_val(pud)))) {
- hpdp = (hugepd_t *)&pud;
- goto out_huge;
- }
- pdshift = PMD_SHIFT;
- pmdp = pmd_offset(&pud, ea);
- pmd = READ_ONCE(*pmdp);
- /*
- * A hugepage collapse is captured by pmd_none, because
- * it mark the pmd none and do a hpte invalidate.
- */
- if (pmd_none(pmd))
- return NULL;
-
- if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
- if (is_thp)
- *is_thp = true;
- ret_pte = (pte_t *)pmdp;
- goto out;
- }
- /*
- * pmd_large check below will handle the swap pmd pte
- * we need to do both the check because they are config
- * dependent.
- */
- if (pmd_huge(pmd) || pmd_large(pmd)) {
- ret_pte = (pte_t *)pmdp;
- goto out;
- }
- if (is_hugepd(__hugepd(pmd_val(pmd)))) {
- hpdp = (hugepd_t *)&pmd;
- goto out_huge;
- }
+ if (pud_none(pud))
+ return NULL;

- return pte_offset_kernel(&pmd, ea);
+ if (pud_huge(pud)) {
+ ret_pte = (pte_t *)pudp;
+ goto out;
}
+ if (is_hugepd(__hugepd(pud_val(pud)))) {
+ hpdp = (hugepd_t *)&pud;
+ goto out_huge;
+ }
+ pdshift = PMD_SHIFT;
+ pmdp = pmd_offset(&pud, ea);
+ pmd = READ_ONCE(*pmdp);
+ /*
+ * A hugepage collapse is captured by pmd_none, because
+ * it mark the pmd none and do a hpte invalidate.
+ */
+ if (pmd_none(pmd))
+ return NULL;
+
+ if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
+ if (is_thp)
+ *is_thp = true;
+ ret_pte = (pte_t *)pmdp;
+ goto out;
+ }
+ /*
+ * pmd_large check below will handle the swap pmd pte
+ * we need to do both the check because they are config
+ * dependent.
+ */
+ if (pmd_huge(pmd) || pmd_large(pmd)) {
+ ret_pte = (pte_t *)pmdp;
+ goto out;
+ }
+ if (is_hugepd(__hugepd(pmd_val(pmd)))) {
+ hpdp = (hugepd_t *)&pmd;
+ goto out_huge;
+ }
+
+ return pte_offset_kernel(&pmd, ea);
+
out_huge:
if (!hpdp)
return NULL;
--
2.13.3


2019-03-20 10:08:40

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 24/27] powerpc: define subarch SLB_ADDR_LIMIT_DEFAULT

This patch defines a subarch specific SLB_ADDR_LIMIT_DEFAULT
to remove the #ifdefs around the setup of mm->context.slb_addr_limit

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/book3s/64/slice.h | 2 ++
arch/powerpc/include/asm/nohash/32/slice.h | 2 ++
arch/powerpc/kernel/setup-common.c | 8 +-------
arch/powerpc/mm/slice.c | 6 +-----
4 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h
index af498b0da21a..8da15958dcd1 100644
--- a/arch/powerpc/include/asm/book3s/64/slice.h
+++ b/arch/powerpc/include/asm/book3s/64/slice.h
@@ -13,6 +13,8 @@
#define SLICE_NUM_HIGH (H_PGTABLE_RANGE >> SLICE_HIGH_SHIFT)
#define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT)

+#define SLB_ADDR_LIMIT_DEFAULT DEFAULT_MAP_WINDOW_USER64
+
#else /* CONFIG_PPC_MM_SLICES */

#define get_slice_psize(mm, addr) ((mm)->context.user_psize)
diff --git a/arch/powerpc/include/asm/nohash/32/slice.h b/arch/powerpc/include/asm/nohash/32/slice.h
index 777d62e40ac0..39eb0154ae2d 100644
--- a/arch/powerpc/include/asm/nohash/32/slice.h
+++ b/arch/powerpc/include/asm/nohash/32/slice.h
@@ -13,6 +13,8 @@
#define SLICE_NUM_HIGH 0ul
#define GET_HIGH_SLICE_INDEX(addr) (addr & 0)

+#define SLB_ADDR_LIMIT_DEFAULT DEFAULT_MAP_WINDOW
+
#endif /* CONFIG_PPC_MM_SLICES */

#endif /* _ASM_POWERPC_NOHASH_32_SLICE_H */
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 2e5dfb6e0823..af2682d052a2 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -948,14 +948,8 @@ void __init setup_arch(char **cmdline_p)
init_mm.brk = klimit;

#ifdef CONFIG_PPC_MM_SLICES
-#ifdef CONFIG_PPC64
if (!radix_enabled())
- init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW_USER64;
-#elif defined(CONFIG_PPC_8xx)
- init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW;
-#else
-#error "context.addr_limit not initialized."
-#endif
+ init_mm.context.slb_addr_limit = SLB_ADDR_LIMIT_DEFAULT;
#endif

#ifdef CONFIG_SPAPR_TCE_IOMMU
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 50b1a5528384..64513cf47e5b 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -652,11 +652,7 @@ void slice_init_new_context_exec(struct mm_struct *mm)
* case of fork it is just inherited from the mm being
* duplicated.
*/
-#ifdef CONFIG_PPC64
- mm->context.slb_addr_limit = DEFAULT_MAP_WINDOW_USER64;
-#else
- mm->context.slb_addr_limit = DEFAULT_MAP_WINDOW;
-#endif
+ mm->context.slb_addr_limit = SLB_ADDR_LIMIT_DEFAULT;

mm->context.user_psize = psize;

--
2.13.3


2019-03-20 10:08:45

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 20/27] powerpc/mm: remove unnecessary #ifdef CONFIG_PPC64

For PPC32 that's a noop, but gcc is smart enough ignore it.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/slice.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 99983dc4e484..f98b9e812c62 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -96,13 +96,11 @@ static int slice_high_has_vma(struct mm_struct *mm, unsigned long slice)
unsigned long start = slice << SLICE_HIGH_SHIFT;
unsigned long end = start + (1ul << SLICE_HIGH_SHIFT);

-#ifdef CONFIG_PPC64
/* Hack, so that each addresses is controlled by exactly one
* of the high or low area bitmaps, the first high area starts
* at 4GB, not 0 */
if (start == 0)
- start = SLICE_LOW_TOP;
-#endif
+ start = (unsigned long)SLICE_LOW_TOP;

return !slice_area_is_free(mm, start, end - start);
}
--
2.13.3


2019-03-20 10:08:59

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 23/27] powerpc/mm: remove a couple of #ifdef CONFIG_PPC_64K_PAGES in mm/slice.c

This patch replaces a couple of #ifdef CONFIG_PPC_64K_PAGES
by IS_ENABLED(CONFIG_PPC_64K_PAGES) to improve code maintainability.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/slice.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 357d64e14757..50b1a5528384 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -558,14 +558,13 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
newaddr = slice_find_area(mm, len, &potential_mask,
psize, topdown, high_limit);

-#ifdef CONFIG_PPC_64K_PAGES
- if (newaddr == -ENOMEM && psize == MMU_PAGE_64K) {
+ if (IS_ENABLED(CONFIG_PPC_64K_PAGES) && newaddr == -ENOMEM &&
+ psize == MMU_PAGE_64K) {
/* retry the search with 4k-page slices included */
slice_or_mask(&potential_mask, &potential_mask, compat_maskp);
newaddr = slice_find_area(mm, len, &potential_mask,
psize, topdown, high_limit);
}
-#endif

if (newaddr == -ENOMEM)
return -ENOMEM;
@@ -731,9 +730,9 @@ int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
VM_BUG_ON(radix_enabled());

maskp = slice_mask_for_size(&mm->context, psize);
-#ifdef CONFIG_PPC_64K_PAGES
+
/* We need to account for 4k slices too */
- if (psize == MMU_PAGE_64K) {
+ if (IS_ENABLED(CONFIG_PPC_64K_PAGES) && psize == MMU_PAGE_64K) {
const struct slice_mask *compat_maskp;
struct slice_mask available;

@@ -741,7 +740,6 @@ int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
slice_or_mask(&available, maskp, compat_maskp);
return !slice_check_range_fits(mm, &available, addr, len);
}
-#endif

return !slice_check_range_fits(mm, maskp, addr, len);
}
--
2.13.3


2019-03-20 10:09:05

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 06/27] powerpc/64: only book3s/64 supports CONFIG_PPC_64K_PAGES

CONFIG_PPC_64K_PAGES cannot be selected by nohash/64

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/Kconfig | 1 -
arch/powerpc/include/asm/nohash/64/pgalloc.h | 3 ---
arch/powerpc/include/asm/nohash/64/pgtable.h | 4 ----
arch/powerpc/include/asm/nohash/64/slice.h | 4 ----
arch/powerpc/include/asm/nohash/pte-book3e.h | 5 -----
arch/powerpc/include/asm/pgtable-be-types.h | 7 ++-----
arch/powerpc/include/asm/pgtable-types.h | 7 ++-----
arch/powerpc/include/asm/task_size_64.h | 2 +-
arch/powerpc/mm/tlb_low_64e.S | 31 ----------------------------
arch/powerpc/mm/tlb_nohash.c | 13 ------------
10 files changed, 5 insertions(+), 72 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2d0be82c3061..5d8e692d6470 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -375,7 +375,6 @@ config ZONE_DMA
config PGTABLE_LEVELS
int
default 2 if !PPC64
- default 3 if PPC_64K_PAGES && !PPC_BOOK3S_64
default 4

source "arch/powerpc/sysdev/Kconfig"
diff --git a/arch/powerpc/include/asm/nohash/64/pgalloc.h b/arch/powerpc/include/asm/nohash/64/pgalloc.h
index 66d086f85bd5..ded453f9b5a8 100644
--- a/arch/powerpc/include/asm/nohash/64/pgalloc.h
+++ b/arch/powerpc/include/asm/nohash/64/pgalloc.h
@@ -171,12 +171,9 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,

#define __pmd_free_tlb(tlb, pmd, addr) \
pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX)
-#ifndef CONFIG_PPC_64K_PAGES
#define __pud_free_tlb(tlb, pud, addr) \
pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)

-#endif /* CONFIG_PPC_64K_PAGES */
-
#define check_pgt_cache() do { } while (0)

#endif /* _ASM_POWERPC_PGALLOC_64_H */
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index e77ed9761632..3efbd8a1720a 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -10,10 +10,6 @@
#include <asm/barrier.h>
#include <asm/asm-const.h>

-#ifdef CONFIG_PPC_64K_PAGES
-#error "Page size not supported"
-#endif
-
#define FIRST_USER_ADDRESS 0UL

/*
diff --git a/arch/powerpc/include/asm/nohash/64/slice.h b/arch/powerpc/include/asm/nohash/64/slice.h
index 1a32d1fae6af..30adfdd4afde 100644
--- a/arch/powerpc/include/asm/nohash/64/slice.h
+++ b/arch/powerpc/include/asm/nohash/64/slice.h
@@ -2,10 +2,6 @@
#ifndef _ASM_POWERPC_NOHASH_64_SLICE_H
#define _ASM_POWERPC_NOHASH_64_SLICE_H

-#ifdef CONFIG_PPC_64K_PAGES
-#define get_slice_psize(mm, addr) MMU_PAGE_64K
-#else /* CONFIG_PPC_64K_PAGES */
#define get_slice_psize(mm, addr) MMU_PAGE_4K
-#endif /* !CONFIG_PPC_64K_PAGES */

#endif /* _ASM_POWERPC_NOHASH_64_SLICE_H */
diff --git a/arch/powerpc/include/asm/nohash/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h
index dd40d200f274..813918f40765 100644
--- a/arch/powerpc/include/asm/nohash/pte-book3e.h
+++ b/arch/powerpc/include/asm/nohash/pte-book3e.h
@@ -60,13 +60,8 @@
#define _PAGE_SPECIAL _PAGE_SW0

/* Base page size */
-#ifdef CONFIG_PPC_64K_PAGES
-#define _PAGE_PSIZE _PAGE_PSIZE_64K
-#define PTE_RPN_SHIFT (28)
-#else
#define _PAGE_PSIZE _PAGE_PSIZE_4K
#define PTE_RPN_SHIFT (24)
-#endif

#define PTE_WIMGE_SHIFT (19)
#define PTE_BAP_SHIFT (2)
diff --git a/arch/powerpc/include/asm/pgtable-be-types.h b/arch/powerpc/include/asm/pgtable-be-types.h
index a89c67b62680..5932a9883eb7 100644
--- a/arch/powerpc/include/asm/pgtable-be-types.h
+++ b/arch/powerpc/include/asm/pgtable-be-types.h
@@ -34,10 +34,8 @@ static inline __be64 pmd_raw(pmd_t x)
}

/*
- * 64 bit hash always use 4 level table. Everybody else use 4 level
- * only for 4K page size.
+ * 64 bit always use 4 level table
*/
-#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES)
typedef struct { __be64 pud; } pud_t;
#define __pud(x) ((pud_t) { cpu_to_be64(x) })
#define __pud_raw(x) ((pud_t) { (x) })
@@ -51,7 +49,6 @@ static inline __be64 pud_raw(pud_t x)
return x.pud;
}

-#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */
#endif /* CONFIG_PPC64 */

/* PGD level */
@@ -77,7 +74,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
* With hash config 64k pages additionally define a bigger "real PTE" type that
* gathers the "second half" part of the PTE for pseudo 64k pages
*/
-#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_BOOK3S_64)
+#ifdef CONFIG_PPC_64K_PAGES
typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
#else
typedef struct { pte_t pte; } real_pte_t;
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
index 3b0edf041b2e..02e75e89c93e 100644
--- a/arch/powerpc/include/asm/pgtable-types.h
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -24,17 +24,14 @@ static inline unsigned long pmd_val(pmd_t x)
}

/*
- * 64 bit hash always use 4 level table. Everybody else use 4 level
- * only for 4K page size.
+ * 64 bit always use 4 level table
*/
-#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES)
typedef struct { unsigned long pud; } pud_t;
#define __pud(x) ((pud_t) { (x) })
static inline unsigned long pud_val(pud_t x)
{
return x.pud;
}
-#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */
#endif /* CONFIG_PPC64 */

/* PGD level */
@@ -54,7 +51,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
* With hash config 64k pages additionally define a bigger "real PTE" type that
* gathers the "second half" part of the PTE for pseudo 64k pages
*/
-#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_BOOK3S_64)
+#ifdef CONFIG_PPC_64K_PAGES
typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
#else
typedef struct { pte_t pte; } real_pte_t;
diff --git a/arch/powerpc/include/asm/task_size_64.h b/arch/powerpc/include/asm/task_size_64.h
index eab4779f6b84..c993482237ed 100644
--- a/arch/powerpc/include/asm/task_size_64.h
+++ b/arch/powerpc/include/asm/task_size_64.h
@@ -20,7 +20,7 @@
/*
* For now 512TB is only supported with book3s and 64K linux page size.
*/
-#if defined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_64K_PAGES)
+#ifdef CONFIG_PPC_64K_PAGES
/*
* Max value currently used:
*/
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 9ed90064f542..58959ce15415 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -24,11 +24,7 @@
#include <asm/kvm_booke_hv_asm.h>
#include <asm/feature-fixups.h>

-#ifdef CONFIG_PPC_64K_PAGES
-#define VPTE_PMD_SHIFT (PTE_INDEX_SIZE+1)
-#else
#define VPTE_PMD_SHIFT (PTE_INDEX_SIZE)
-#endif
#define VPTE_PUD_SHIFT (VPTE_PMD_SHIFT + PMD_INDEX_SIZE)
#define VPTE_PGD_SHIFT (VPTE_PUD_SHIFT + PUD_INDEX_SIZE)
#define VPTE_INDEX_SIZE (VPTE_PGD_SHIFT + PGD_INDEX_SIZE)
@@ -167,13 +163,11 @@ MMU_FTR_SECTION_ELSE
ldx r14,r14,r15 /* grab pgd entry */
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV)

-#ifndef CONFIG_PPC_64K_PAGES
rldicl r15,r16,64-PUD_SHIFT+3,64-PUD_INDEX_SIZE-3
clrrdi r15,r15,3
cmpdi cr0,r14,0
bge tlb_miss_fault_bolted /* Bad pgd entry or hugepage; bail */
ldx r14,r14,r15 /* grab pud entry */
-#endif /* CONFIG_PPC_64K_PAGES */

rldicl r15,r16,64-PMD_SHIFT+3,64-PMD_INDEX_SIZE-3
clrrdi r15,r15,3
@@ -682,18 +676,7 @@ normal_tlb_miss:
* order to handle the weird page table format used by linux
*/
ori r10,r15,0x1
-#ifdef CONFIG_PPC_64K_PAGES
- /* For the top bits, 16 bytes per PTE */
- rldicl r14,r16,64-(PAGE_SHIFT-4),PAGE_SHIFT-4+4
- /* Now create the bottom bits as 0 in position 0x8000 and
- * the rest calculated for 8 bytes per PTE
- */
- rldicl r15,r16,64-(PAGE_SHIFT-3),64-15
- /* Insert the bottom bits in */
- rlwimi r14,r15,0,16,31
-#else
rldicl r14,r16,64-(PAGE_SHIFT-3),PAGE_SHIFT-3+4
-#endif
sldi r15,r10,60
clrrdi r14,r14,3
or r10,r15,r14
@@ -732,11 +715,7 @@ finish_normal_tlb_miss:

/* Check page size, if not standard, update MAS1 */
rldicl r11,r14,64-8,64-8
-#ifdef CONFIG_PPC_64K_PAGES
- cmpldi cr0,r11,BOOK3E_PAGESZ_64K
-#else
cmpldi cr0,r11,BOOK3E_PAGESZ_4K
-#endif
beq- 1f
mfspr r11,SPRN_MAS1
rlwimi r11,r14,31,21,24
@@ -857,14 +836,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
cmpdi cr0,r15,0
bge virt_page_table_tlb_miss_fault

-#ifndef CONFIG_PPC_64K_PAGES
/* Get to PUD entry */
rldicl r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3
clrrdi r10,r11,3
ldx r15,r10,r15
cmpdi cr0,r15,0
bge virt_page_table_tlb_miss_fault
-#endif /* CONFIG_PPC_64K_PAGES */

/* Get to PMD entry */
rldicl r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3
@@ -1106,14 +1083,12 @@ htw_tlb_miss:
cmpdi cr0,r15,0
bge htw_tlb_miss_fault

-#ifndef CONFIG_PPC_64K_PAGES
/* Get to PUD entry */
rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
clrrdi r10,r11,3
ldx r15,r10,r15
cmpdi cr0,r15,0
bge htw_tlb_miss_fault
-#endif /* CONFIG_PPC_64K_PAGES */

/* Get to PMD entry */
rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
@@ -1132,9 +1107,7 @@ htw_tlb_miss:
* 4K page we need to extract a bit from the virtual address and
* insert it into the "PA52" bit of the RPN.
*/
-#ifndef CONFIG_PPC_64K_PAGES
rlwimi r15,r16,32-9,20,20
-#endif
/* Now we build the MAS:
*
* MAS 0 : Fully setup with defaults in MAS4 and TLBnCFG
@@ -1144,11 +1117,7 @@ htw_tlb_miss:
* MAS 2 : Use defaults
* MAS 3+7 : Needs to be done
*/
-#ifdef CONFIG_PPC_64K_PAGES
- ori r10,r15,(BOOK3E_PAGESZ_64K << MAS3_SPSIZE_SHIFT)
-#else
ori r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
-#endif

BEGIN_MMU_FTR_SECTION
srdi r16,r10,32
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index ac23dc1c6535..b892e5b3010c 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -433,11 +433,7 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
unsigned long rid = (address & rmask) | 0x1000000000000000ul;
unsigned long vpte = address & ~rmask;

-#ifdef CONFIG_PPC_64K_PAGES
- vpte = (vpte >> (PAGE_SHIFT - 4)) & ~0xfffful;
-#else
vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
-#endif
vpte |= rid;
__flush_tlb_page(tlb->mm, vpte, tsize, 0);
}
@@ -625,21 +621,12 @@ static void early_init_this_mmu(void)

case PPC_HTW_IBM:
mas4 |= MAS4_INDD;
-#ifdef CONFIG_PPC_64K_PAGES
- mas4 |= BOOK3E_PAGESZ_256M << MAS4_TSIZED_SHIFT;
- mmu_pte_psize = MMU_PAGE_256M;
-#else
mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT;
mmu_pte_psize = MMU_PAGE_1M;
-#endif
break;

case PPC_HTW_NONE:
-#ifdef CONFIG_PPC_64K_PAGES
- mas4 |= BOOK3E_PAGESZ_64K << MAS4_TSIZED_SHIFT;
-#else
mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
-#endif
mmu_pte_psize = mmu_virtual_psize;
break;
}
--
2.13.3


2019-03-20 10:09:11

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 19/27] powerpc/mm: drop slice DEBUG

slice is now an improved functionnality. Drop the DEBUG stuff.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/slice.c | 62 ++++---------------------------------------------
1 file changed, 4 insertions(+), 58 deletions(-)

diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 011d470ea340..99983dc4e484 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -41,28 +41,6 @@

static DEFINE_SPINLOCK(slice_convert_lock);

-#ifdef DEBUG
-int _slice_debug = 1;
-
-static void slice_print_mask(const char *label, const struct slice_mask *mask)
-{
- if (!_slice_debug)
- return;
- pr_devel("%s low_slice: %*pbl\n", label,
- (int)SLICE_NUM_LOW, &mask->low_slices);
- pr_devel("%s high_slice: %*pbl\n", label,
- (int)SLICE_NUM_HIGH, mask->high_slices);
-}
-
-#define slice_dbg(fmt...) do { if (_slice_debug) pr_devel(fmt); } while (0)
-
-#else
-
-static void slice_print_mask(const char *label, const struct slice_mask *mask) {}
-#define slice_dbg(fmt...)
-
-#endif
-
static inline bool slice_addr_is_low(unsigned long addr)
{
u64 tmp = (u64)addr;
@@ -245,9 +223,6 @@ static void slice_convert(struct mm_struct *mm,
unsigned long i, flags;
int old_psize;

- slice_dbg("slice_convert(mm=%p, psize=%d)\n", mm, psize);
- slice_print_mask(" mask", mask);
-
psize_mask = slice_mask_for_size(mm, psize);

/* We need to use a spinlock here to protect against
@@ -293,10 +268,6 @@ static void slice_convert(struct mm_struct *mm,
(((unsigned long)psize) << (mask_index * 4));
}

- slice_dbg(" lsps=%lx, hsps=%lx\n",
- (unsigned long)mm->context.low_slices_psize,
- (unsigned long)mm->context.high_slices_psize);
-
spin_unlock_irqrestore(&slice_convert_lock, flags);

copro_flush_all_slbs(mm);
@@ -523,14 +494,9 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
BUG_ON(mm->context.slb_addr_limit == 0);
VM_BUG_ON(radix_enabled());

- slice_dbg("slice_get_unmapped_area(mm=%p, psize=%d...\n", mm, psize);
- slice_dbg(" addr=%lx, len=%lx, flags=%lx, topdown=%d\n",
- addr, len, flags, topdown);
-
/* If hint, make sure it matches our alignment restrictions */
if (!fixed && addr) {
addr = _ALIGN_UP(addr, page_size);
- slice_dbg(" aligned addr=%lx\n", addr);
/* Ignore hint if it's too large or overlaps a VMA */
if (addr > high_limit - len || addr < mmap_min_addr ||
!slice_area_is_free(mm, addr, len))
@@ -576,17 +542,12 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
slice_copy_mask(&good_mask, maskp);
}

- slice_print_mask(" good_mask", &good_mask);
- if (compat_maskp)
- slice_print_mask(" compat_mask", compat_maskp);
-
/* First check hint if it's valid or if we have MAP_FIXED */
if (addr != 0 || fixed) {
/* Check if we fit in the good mask. If we do, we just return,
* nothing else to do
*/
if (slice_check_range_fits(mm, &good_mask, addr, len)) {
- slice_dbg(" fits good !\n");
newaddr = addr;
goto return_addr;
}
@@ -596,13 +557,10 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
*/
newaddr = slice_find_area(mm, len, &good_mask,
psize, topdown, high_limit);
- if (newaddr != -ENOMEM) {
- /* Found within the good mask, we don't have to setup,
- * we thus return directly
- */
- slice_dbg(" found area at 0x%lx\n", newaddr);
+
+ /* Found within good mask, don't have to setup, thus return directly */
+ if (newaddr != -ENOMEM)
goto return_addr;
- }
}
/*
* We don't fit in the good mask, check what other slices are
@@ -610,11 +568,9 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
*/
slice_mask_for_free(mm, &potential_mask, high_limit);
slice_or_mask(&potential_mask, &potential_mask, &good_mask);
- slice_print_mask(" potential", &potential_mask);

if (addr != 0 || fixed) {
if (slice_check_range_fits(mm, &potential_mask, addr, len)) {
- slice_dbg(" fits potential !\n");
newaddr = addr;
goto convert;
}
@@ -624,18 +580,14 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
if (fixed)
return -EBUSY;

- slice_dbg(" search...\n");
-
/* If we had a hint that didn't work out, see if we can fit
* anywhere in the good area.
*/
if (addr) {
newaddr = slice_find_area(mm, len, &good_mask,
psize, topdown, high_limit);
- if (newaddr != -ENOMEM) {
- slice_dbg(" found area at 0x%lx\n", newaddr);
+ if (newaddr != -ENOMEM)
goto return_addr;
- }
}

/* Now let's see if we can find something in the existing slices
@@ -657,8 +609,6 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
return -ENOMEM;

slice_range_to_mask(newaddr, len, &potential_mask);
- slice_dbg(" found potential area at 0x%lx\n", newaddr);
- slice_print_mask(" mask", &potential_mask);

convert:
/*
@@ -736,8 +686,6 @@ void slice_init_new_context_exec(struct mm_struct *mm)
struct slice_mask *mask;
unsigned int psize = mmu_virtual_psize;

- slice_dbg("slice_init_new_context_exec(mm=%p)\n", mm);
-
/*
* In the case of exec, use the default limit. In the
* case of fork it is just inherited from the mm being
@@ -774,8 +722,6 @@ void slice_setup_new_exec(void)
{
struct mm_struct *mm = current->mm;

- slice_dbg("slice_setup_new_exec(mm=%p)\n", mm);
-
if (!is_32bit_task())
return;

--
2.13.3


2019-03-20 10:09:15

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 21/27] powerpc/mm: hand a context_t over to slice_mask_for_size() instead of mm_struct

slice_mask_for_size() only uses mm->context, so hand directly a
pointer to the context. This will help moving the function in
subarch mmu.h in the next patch by avoiding having to include
the definition of struct mm_struct

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/slice.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index f98b9e812c62..231fd88d97e2 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -127,33 +127,33 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret,
}

#ifdef CONFIG_PPC_BOOK3S_64
-static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
+static struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
{
#ifdef CONFIG_PPC_64K_PAGES
if (psize == MMU_PAGE_64K)
- return &mm->context.mask_64k;
+ return &ctx->mask_64k;
#endif
if (psize == MMU_PAGE_4K)
- return &mm->context.mask_4k;
+ return &ctx->mask_4k;
#ifdef CONFIG_HUGETLB_PAGE
if (psize == MMU_PAGE_16M)
- return &mm->context.mask_16m;
+ return &ctx->mask_16m;
if (psize == MMU_PAGE_16G)
- return &mm->context.mask_16g;
+ return &ctx->mask_16g;
#endif
WARN_ON(true);
return NULL;
}
#elif defined(CONFIG_PPC_8xx)
-static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
+static struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
{
if (psize == mmu_virtual_psize)
- return &mm->context.mask_base_psize;
+ return &ctx->mask_base_psize;
#ifdef CONFIG_HUGETLB_PAGE
if (psize == MMU_PAGE_512K)
- return &mm->context.mask_512k;
+ return &ctx->mask_512k;
if (psize == MMU_PAGE_8M)
- return &mm->context.mask_8m;
+ return &ctx->mask_8m;
#endif
WARN_ON(true);
return NULL;
@@ -221,7 +221,7 @@ static void slice_convert(struct mm_struct *mm,
unsigned long i, flags;
int old_psize;

- psize_mask = slice_mask_for_size(mm, psize);
+ psize_mask = slice_mask_for_size(&mm->context, psize);

/* We need to use a spinlock here to protect against
* concurrent 64k -> 4k demotion ...
@@ -238,7 +238,7 @@ static void slice_convert(struct mm_struct *mm,

/* Update the slice_mask */
old_psize = (lpsizes[index] >> (mask_index * 4)) & 0xf;
- old_mask = slice_mask_for_size(mm, old_psize);
+ old_mask = slice_mask_for_size(&mm->context, old_psize);
old_mask->low_slices &= ~(1u << i);
psize_mask->low_slices |= 1u << i;

@@ -257,7 +257,7 @@ static void slice_convert(struct mm_struct *mm,

/* Update the slice_mask */
old_psize = (hpsizes[index] >> (mask_index * 4)) & 0xf;
- old_mask = slice_mask_for_size(mm, old_psize);
+ old_mask = slice_mask_for_size(&mm->context, old_psize);
__clear_bit(i, old_mask->high_slices);
__set_bit(i, psize_mask->high_slices);

@@ -504,7 +504,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
/* First make up a "good" mask of slices that have the right size
* already
*/
- maskp = slice_mask_for_size(mm, psize);
+ maskp = slice_mask_for_size(&mm->context, psize);

/*
* Here "good" means slices that are already the right page size,
@@ -531,7 +531,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
* a pointer to good mask for the next code to use.
*/
if (IS_ENABLED(CONFIG_PPC_64K_PAGES) && psize == MMU_PAGE_64K) {
- compat_maskp = slice_mask_for_size(mm, MMU_PAGE_4K);
+ compat_maskp = slice_mask_for_size(&mm->context, MMU_PAGE_4K);
if (fixed)
slice_or_mask(&good_mask, maskp, compat_maskp);
else
@@ -709,7 +709,7 @@ void slice_init_new_context_exec(struct mm_struct *mm)
/*
* Slice mask cache starts zeroed, fill the default size cache.
*/
- mask = slice_mask_for_size(mm, psize);
+ mask = slice_mask_for_size(&mm->context, psize);
mask->low_slices = ~0UL;
if (SLICE_NUM_HIGH)
bitmap_fill(mask->high_slices, SLICE_NUM_HIGH);
@@ -766,14 +766,14 @@ int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,

VM_BUG_ON(radix_enabled());

- maskp = slice_mask_for_size(mm, psize);
+ maskp = slice_mask_for_size(&mm->context, psize);
#ifdef CONFIG_PPC_64K_PAGES
/* We need to account for 4k slices too */
if (psize == MMU_PAGE_64K) {
const struct slice_mask *compat_maskp;
struct slice_mask available;

- compat_maskp = slice_mask_for_size(mm, MMU_PAGE_4K);
+ compat_maskp = slice_mask_for_size(&mm->context, MMU_PAGE_4K);
slice_or_mask(&available, maskp, compat_maskp);
return !slice_check_range_fits(mm, &available, addr, len);
}
--
2.13.3


2019-03-20 10:09:22

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 13/27] powerpc/mm: define get_slice_psize() all the time

get_slice_psize() can be defined regardless of CONFIG_PPC_MM_SLICES
to avoid ifdefs

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/slice.h | 4 ++++
arch/powerpc/mm/hugetlbpage.c | 4 +---
2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/slice.h b/arch/powerpc/include/asm/slice.h
index 44816cbc4198..d85c85422fdf 100644
--- a/arch/powerpc/include/asm/slice.h
+++ b/arch/powerpc/include/asm/slice.h
@@ -38,6 +38,10 @@ void slice_setup_new_exec(void);

static inline void slice_init_new_context_exec(struct mm_struct *mm) {}

+#ifndef get_slice_psize
+#define get_slice_psize(mm, addr) MMU_PAGE_4K
+#endif
+
#endif /* CONFIG_PPC_MM_SLICES */

#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 26a57ebaf5cf..87358b89513e 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -540,14 +540,12 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,

unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
{
-#ifdef CONFIG_PPC_MM_SLICES
/* With radix we don't use slice, so derive it from vma*/
- if (!radix_enabled()) {
+ if (IS_ENABLED(CONFIG_PPC_MM_SLICES) && !radix_enabled()) {
unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);

return 1UL << mmu_psize_to_shift(psize);
}
-#endif
return vma_kernel_pagesize(vma);
}

--
2.13.3


2019-03-20 10:09:22

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 15/27] powerpc/mm: cleanup ifdef mess in add_huge_page_size()

Introduce a subarch specific helper check_and_get_huge_psize()
to check the huge page sizes and cleanup the ifdef mess in
add_huge_page_size()

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/book3s/64/hugetlb.h | 27 +++++++++++++++++
arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 5 ++++
arch/powerpc/include/asm/nohash/hugetlb-book3e.h | 8 +++++
arch/powerpc/mm/hugetlbpage.c | 37 ++----------------------
4 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index 177c81079209..4522a56a6269 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -108,4 +108,31 @@ static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshi

void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);

+static inline int check_and_get_huge_psize(int shift)
+{
+ int mmu_psize;
+
+ if (shift > SLICE_HIGH_SHIFT)
+ return -EINVAL;
+
+ mmu_psize = shift_to_mmu_psize(shift);
+
+ /*
+ * We need to make sure that for different page sizes reported by
+ * firmware we only add hugetlb support for page sizes that can be
+ * supported by linux page table layout.
+ * For now we have
+ * Radix: 2M and 1G
+ * Hash: 16M and 16G
+ */
+ if (radix_enabled()) {
+ if (mmu_psize != MMU_PAGE_2M && mmu_psize != MMU_PAGE_1G)
+ return -EINVAL;
+ } else {
+ if (mmu_psize != MMU_PAGE_16M && mmu_psize != MMU_PAGE_16G)
+ return -EINVAL;
+ }
+ return mmu_psize;
+}
+
#endif
diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
index eb90c2db7601..a442b499d5c8 100644
--- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -37,4 +37,9 @@ static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshi
(pshift == PAGE_SHIFT_8M ? _PMD_PAGE_8M : _PMD_PAGE_512K));
}

+static inline int check_and_get_huge_psize(int shift)
+{
+ return shift_to_mmu_psize(shift);
+}
+
#endif /* _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H */
diff --git a/arch/powerpc/include/asm/nohash/hugetlb-book3e.h b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
index 51439bcfe313..ecd8694cb229 100644
--- a/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
+++ b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
@@ -34,4 +34,12 @@ static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshi
*hpdp = __hugepd(((unsigned long)new & ~PD_HUGE) | pshift);
}

+static inline int check_and_get_huge_psize(int shift)
+{
+ if (shift & 1) /* Not a power of 4 */
+ return -EINVAL;
+
+ return shift_to_mmu_psize(shift);
+}
+
#endif /* _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 87358b89513e..3b449c9d4e47 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -549,13 +549,6 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
return vma_kernel_pagesize(vma);
}

-static inline bool is_power_of_4(unsigned long x)
-{
- if (is_power_of_2(x))
- return (__ilog2(x) % 2) ? false : true;
- return false;
-}
-
static int __init add_huge_page_size(unsigned long long size)
{
int shift = __ffs(size);
@@ -563,37 +556,13 @@ static int __init add_huge_page_size(unsigned long long size)

/* Check that it is a page size supported by the hardware and
* that it fits within pagetable and slice limits. */
- if (size <= PAGE_SIZE)
- return -EINVAL;
-#if defined(CONFIG_PPC_FSL_BOOK3E)
- if (!is_power_of_4(size))
+ if (size <= PAGE_SIZE || !is_power_of_2(size))
return -EINVAL;
-#elif !defined(CONFIG_PPC_8xx)
- if (!is_power_of_2(size) || (shift > SLICE_HIGH_SHIFT))
- return -EINVAL;
-#endif

- if ((mmu_psize = shift_to_mmu_psize(shift)) < 0)
+ mmu_psize = check_and_get_huge_psize(size);
+ if (mmu_psize < 0)
return -EINVAL;

-#ifdef CONFIG_PPC_BOOK3S_64
- /*
- * We need to make sure that for different page sizes reported by
- * firmware we only add hugetlb support for page sizes that can be
- * supported by linux page table layout.
- * For now we have
- * Radix: 2M and 1G
- * Hash: 16M and 16G
- */
- if (radix_enabled()) {
- if (mmu_psize != MMU_PAGE_2M && mmu_psize != MMU_PAGE_1G)
- return -EINVAL;
- } else {
- if (mmu_psize != MMU_PAGE_16M && mmu_psize != MMU_PAGE_16G)
- return -EINVAL;
- }
-#endif
-
if (WARN_ON(mmu_psize_defs[mmu_psize].shift != shift))
return -EINVAL;

--
2.13.3


2019-03-20 10:09:32

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 14/27] powerpc/mm: no slice for nohash/64

Only nohash/32 and book3s/64 support mm slices.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/nohash/64/slice.h | 7 -------
arch/powerpc/include/asm/slice.h | 4 +---
arch/powerpc/platforms/Kconfig.cputype | 4 ++++
3 files changed, 5 insertions(+), 10 deletions(-)
delete mode 100644 arch/powerpc/include/asm/nohash/64/slice.h

diff --git a/arch/powerpc/include/asm/nohash/64/slice.h b/arch/powerpc/include/asm/nohash/64/slice.h
deleted file mode 100644
index 30adfdd4afde..000000000000
--- a/arch/powerpc/include/asm/nohash/64/slice.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_POWERPC_NOHASH_64_SLICE_H
-#define _ASM_POWERPC_NOHASH_64_SLICE_H
-
-#define get_slice_psize(mm, addr) MMU_PAGE_4K
-
-#endif /* _ASM_POWERPC_NOHASH_64_SLICE_H */
diff --git a/arch/powerpc/include/asm/slice.h b/arch/powerpc/include/asm/slice.h
index d85c85422fdf..49d950a14e25 100644
--- a/arch/powerpc/include/asm/slice.h
+++ b/arch/powerpc/include/asm/slice.h
@@ -4,9 +4,7 @@

#ifdef CONFIG_PPC_BOOK3S_64
#include <asm/book3s/64/slice.h>
-#elif defined(CONFIG_PPC64)
-#include <asm/nohash/64/slice.h>
-#elif defined(CONFIG_PPC_MMU_NOHASH)
+#elif defined(CONFIG_PPC_MMU_NOHASH_32)
#include <asm/nohash/32/slice.h>
#endif

diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 842b2c7e156a..51ceeb046867 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -354,6 +354,10 @@ config PPC_MMU_NOHASH
def_bool y
depends on !PPC_BOOK3S

+config PPC_MMU_NOHASH_32
+ def_bool y
+ depends on PPC_MMU_NOHASH && PPC32
+
config PPC_BOOK3E_MMU
def_bool y
depends on FSL_BOOKE || PPC_BOOK3E
--
2.13.3


2019-03-20 10:09:38

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 10/27] powerpc/mm: make gup_hugepte() static

gup_huge_pd() is the only user of gup_hugepte() and it is
located in the same file. This patch moves gup_huge_pd()
after gup_hugepte() and makes gup_hugepte() static.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/pgtable.h | 3 ---
arch/powerpc/mm/hugetlbpage.c | 38 +++++++++++++++++++-------------------
2 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 505550fb2935..c51846da41a7 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -89,9 +89,6 @@ extern void paging_init(void);
*/
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);

-extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
- unsigned long end, int write,
- struct page **pages, int *nr);
#ifndef CONFIG_TRANSPARENT_HUGEPAGE
#define pmd_large(pmd) 0
#endif
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 6d9751b188c1..29d1568c7775 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -539,23 +539,6 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
return (__boundary - 1 < end - 1) ? __boundary : end;
}

-int gup_huge_pd(hugepd_t hugepd, unsigned long addr, unsigned pdshift,
- unsigned long end, int write, struct page **pages, int *nr)
-{
- pte_t *ptep;
- unsigned long sz = 1UL << hugepd_shift(hugepd);
- unsigned long next;
-
- ptep = hugepte_offset(hugepd, addr, pdshift);
- do {
- next = hugepte_addr_end(addr, end, sz);
- if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
- return 0;
- } while (ptep++, addr = next, addr != end);
-
- return 1;
-}
-
#ifdef CONFIG_PPC_MM_SLICES
unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
unsigned long len, unsigned long pgoff,
@@ -754,8 +737,8 @@ void flush_dcache_icache_hugepage(struct page *page)
}
}

-int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
- unsigned long end, int write, struct page **pages, int *nr)
+static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
+ unsigned long end, int write, struct page **pages, int *nr)
{
unsigned long pte_end;
struct page *head, *page;
@@ -801,3 +784,20 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,

return 1;
}
+
+int gup_huge_pd(hugepd_t hugepd, unsigned long addr, unsigned int pdshift,
+ unsigned long end, int write, struct page **pages, int *nr)
+{
+ pte_t *ptep;
+ unsigned long sz = 1UL << hugepd_shift(hugepd);
+ unsigned long next;
+
+ ptep = hugepte_offset(hugepd, addr, pdshift);
+ do {
+ next = hugepte_addr_end(addr, end, sz);
+ if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
+ return 0;
+ } while (ptep++, addr = next, addr != end);
+
+ return 1;
+}
--
2.13.3


2019-03-20 10:09:38

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 16/27] powerpc/mm: move hugetlb_disabled into asm/hugetlb.h

No need to have this in asm/page.h, move it into asm/hugetlb.h

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/hugetlb.h | 2 ++
arch/powerpc/include/asm/page.h | 1 -
arch/powerpc/kernel/fadump.c | 1 +
arch/powerpc/mm/hash_utils_64.c | 1 +
4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index fd5c0873a57d..84598c6b0959 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -13,6 +13,8 @@
#include <asm/nohash/32/hugetlb-8xx.h>
#endif /* CONFIG_PPC_BOOK3S_64 */

+extern bool hugetlb_disabled;
+
void flush_dcache_icache_hugepage(struct page *page);

int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index ed870468ef6f..0c11a7513919 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -29,7 +29,6 @@

#ifndef __ASSEMBLY__
#ifdef CONFIG_HUGETLB_PAGE
-extern bool hugetlb_disabled;
extern unsigned int HPAGE_SHIFT;
#else
#define HPAGE_SHIFT PAGE_SHIFT
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 45a8d0be1c96..25f063f56ec5 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -36,6 +36,7 @@
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/cma.h>
+#include <linux/hugetlb.h>

#include <asm/debugfs.h>
#include <asm/page.h>
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 0a4f939a8161..16ce13af6b9c 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -37,6 +37,7 @@
#include <linux/context_tracking.h>
#include <linux/libfdt.h>
#include <linux/pkeys.h>
+#include <linux/hugetlb.h>

#include <asm/debugfs.h>
#include <asm/processor.h>
--
2.13.3


2019-03-20 10:09:42

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 12/27] powerpc/mm: add a helper to populate hugepd

This patchs adds a subarch helper to populate hugepd.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/book3s/64/hugetlb.h | 5 +++++
arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 8 ++++++++
arch/powerpc/include/asm/nohash/hugetlb-book3e.h | 6 ++++++
arch/powerpc/mm/hugetlbpage.c | 20 +-------------------
4 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index 2f9cf2bc601c..177c81079209 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -101,6 +101,11 @@ static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
return hugepd_page(hpd) + idx;
}

+static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
+{
+ *hpdp = __hugepd(__pa(new) | HUGEPD_VAL_BITS | (shift_to_mmu_psize(pshift) << 2));
+}
+
void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);

#endif
diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
index 209e6a219835..eb90c2db7601 100644
--- a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -2,6 +2,8 @@
#ifndef _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H
#define _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H

+#define PAGE_SHIFT_8M 23
+
static inline pte_t *hugepd_page(hugepd_t hpd)
{
if (WARN_ON(!hugepd_ok(hpd)))
@@ -29,4 +31,10 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
flush_tlb_page(vma, vmaddr);
}

+static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
+{
+ *hpdp = __hugepd(__pa(new) | _PMD_USER | _PMD_PRESENT |
+ (pshift == PAGE_SHIFT_8M ? _PMD_PAGE_8M : _PMD_PAGE_512K));
+}
+
#endif /* _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H */
diff --git a/arch/powerpc/include/asm/nohash/hugetlb-book3e.h b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
index e94f1cd048ee..51439bcfe313 100644
--- a/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
+++ b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
@@ -28,4 +28,10 @@ static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,

void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);

+static inline void hugepd_populate(hugepd_t *hpdp, pte_t *new, unsigned int pshift)
+{
+ /* We use the old format for PPC_FSL_BOOK3E */
+ *hpdp = __hugepd(((unsigned long)new & ~PD_HUGE) | pshift);
+}
+
#endif /* _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 29d1568c7775..26a57ebaf5cf 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -26,12 +26,6 @@
#include <asm/hugetlb.h>
#include <asm/pte-walk.h>

-#define PAGE_SHIFT_64K 16
-#define PAGE_SHIFT_512K 19
-#define PAGE_SHIFT_8M 23
-#define PAGE_SHIFT_16M 24
-#define PAGE_SHIFT_16G 34
-
bool hugetlb_disabled = false;

unsigned int HPAGE_SHIFT;
@@ -95,19 +89,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
for (i = 0; i < num_hugepd; i++, hpdp++) {
if (unlikely(!hugepd_none(*hpdp)))
break;
- else {
-#ifdef CONFIG_PPC_BOOK3S_64
- *hpdp = __hugepd(__pa(new) | HUGEPD_VAL_BITS |
- (shift_to_mmu_psize(pshift) << 2));
-#elif defined(CONFIG_PPC_8xx)
- *hpdp = __hugepd(__pa(new) | _PMD_USER |
- (pshift == PAGE_SHIFT_8M ? _PMD_PAGE_8M :
- _PMD_PAGE_512K) | _PMD_PRESENT);
-#else
- /* We use the old format for PPC_FSL_BOOK3E */
- *hpdp = __hugepd(((unsigned long)new & ~PD_HUGE) | pshift);
-#endif
- }
+ hugepd_populate(hpdp, new, pshift);
}
/* If we bailed from the for loop early, an error occurred, clean up */
if (i < num_hugepd) {
--
2.13.3


2019-03-20 10:09:55

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 07/27] powerpc/book3e: hugetlbpage is only for CONFIG_PPC_FSL_BOOK3E

As per Kconfig.cputype, only CONFIG_PPC_FSL_BOOK3E gets to
select SYS_SUPPORTS_HUGETLBFS so simplify accordingly.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/Makefile | 2 +-
arch/powerpc/mm/hugetlbpage-book3e.c | 47 +++++++++++++++---------------------
2 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 3c1bd9fa23cd..2c23d1ece034 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -37,7 +37,7 @@ obj-y += hugetlbpage.o
ifdef CONFIG_HUGETLB_PAGE
obj-$(CONFIG_PPC_BOOK3S_64) += hugetlbpage-hash64.o
obj-$(CONFIG_PPC_RADIX_MMU) += hugetlbpage-radix.o
-obj-$(CONFIG_PPC_BOOK3E_MMU) += hugetlbpage-book3e.o
+obj-$(CONFIG_PPC_FSL_BOOK3E) += hugetlbpage-book3e.o
endif
obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += hugepage-hash64.o
obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
index c911fe9bfa0e..61915f4d3c7f 100644
--- a/arch/powerpc/mm/hugetlbpage-book3e.c
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -11,8 +11,9 @@

#include <asm/mmu.h>

-#ifdef CONFIG_PPC_FSL_BOOK3E
#ifdef CONFIG_PPC64
+#include <asm/paca.h>
+
static inline int tlb1_next(void)
{
struct paca_struct *paca = get_paca();
@@ -29,28 +30,6 @@ static inline int tlb1_next(void)
tcd->esel_next = next;
return this;
}
-#else
-static inline int tlb1_next(void)
-{
- int index, ncams;
-
- ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
-
- index = this_cpu_read(next_tlbcam_idx);
-
- /* Just round-robin the entries and wrap when we hit the end */
- if (unlikely(index == ncams - 1))
- __this_cpu_write(next_tlbcam_idx, tlbcam_index);
- else
- __this_cpu_inc(next_tlbcam_idx);
-
- return index;
-}
-#endif /* !PPC64 */
-#endif /* FSL */
-
-#if defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_PPC64)
-#include <asm/paca.h>

static inline void book3e_tlb_lock(void)
{
@@ -93,6 +72,23 @@ static inline void book3e_tlb_unlock(void)
paca->tcd_ptr->lock = 0;
}
#else
+static inline int tlb1_next(void)
+{
+ int index, ncams;
+
+ ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
+
+ index = this_cpu_read(next_tlbcam_idx);
+
+ /* Just round-robin the entries and wrap when we hit the end */
+ if (unlikely(index == ncams - 1))
+ __this_cpu_write(next_tlbcam_idx, tlbcam_index);
+ else
+ __this_cpu_inc(next_tlbcam_idx);
+
+ return index;
+}
+
static inline void book3e_tlb_lock(void)
{
}
@@ -134,10 +130,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
unsigned long psize, tsize, shift;
unsigned long flags;
struct mm_struct *mm;
-
-#ifdef CONFIG_PPC_FSL_BOOK3E
int index;
-#endif

if (unlikely(is_kernel_addr(ea)))
return;
@@ -161,11 +154,9 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
return;
}

-#ifdef CONFIG_PPC_FSL_BOOK3E
/* We have to use the CAM(TLB1) on FSL parts for hugepages */
index = tlb1_next();
mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1));
-#endif

mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize);
mas2 = ea & ~((1UL << shift) - 1);
--
2.13.3


2019-03-20 10:10:08

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 08/27] powerpc/mm: move __find_linux_pte() out of hugetlbpage.c

__find_linux_pte() is the only function in hugetlbpage.c
which is compiled in regardless on CONFIG_HUGETLBPAGE

This patch moves it in pgtable.c.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/hugetlbpage.c | 103 -----------------------------------------
arch/powerpc/mm/pgtable.c | 104 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 103 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index cf2978e235f3..202ae006aa39 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -759,109 +759,6 @@ void flush_dcache_icache_hugepage(struct page *page)

#endif /* CONFIG_HUGETLB_PAGE */

-/*
- * We have 4 cases for pgds and pmds:
- * (1) invalid (all zeroes)
- * (2) pointer to next table, as normal; bottom 6 bits == 0
- * (3) leaf pte for huge page _PAGE_PTE set
- * (4) hugepd pointer, _PAGE_PTE = 0 and bits [2..6] indicate size of table
- *
- * So long as we atomically load page table pointers we are safe against teardown,
- * we can follow the address down to the the page and take a ref on it.
- * This function need to be called with interrupts disabled. We use this variant
- * when we have MSR[EE] = 0 but the paca->irq_soft_mask = IRQS_ENABLED
- */
-pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
- bool *is_thp, unsigned *hpage_shift)
-{
- pgd_t pgd, *pgdp;
- pud_t pud, *pudp;
- pmd_t pmd, *pmdp;
- pte_t *ret_pte;
- hugepd_t *hpdp = NULL;
- unsigned pdshift = PGDIR_SHIFT;
-
- if (hpage_shift)
- *hpage_shift = 0;
-
- if (is_thp)
- *is_thp = false;
-
- pgdp = pgdir + pgd_index(ea);
- pgd = READ_ONCE(*pgdp);
- /*
- * Always operate on the local stack value. This make sure the
- * value don't get updated by a parallel THP split/collapse,
- * page fault or a page unmap. The return pte_t * is still not
- * stable. So should be checked there for above conditions.
- */
- if (pgd_none(pgd))
- return NULL;
- else if (pgd_huge(pgd)) {
- ret_pte = (pte_t *) pgdp;
- goto out;
- } else if (is_hugepd(__hugepd(pgd_val(pgd))))
- hpdp = (hugepd_t *)&pgd;
- else {
- /*
- * Even if we end up with an unmap, the pgtable will not
- * be freed, because we do an rcu free and here we are
- * irq disabled
- */
- pdshift = PUD_SHIFT;
- pudp = pud_offset(&pgd, ea);
- pud = READ_ONCE(*pudp);
-
- if (pud_none(pud))
- return NULL;
- else if (pud_huge(pud)) {
- ret_pte = (pte_t *) pudp;
- goto out;
- } else if (is_hugepd(__hugepd(pud_val(pud))))
- hpdp = (hugepd_t *)&pud;
- else {
- pdshift = PMD_SHIFT;
- pmdp = pmd_offset(&pud, ea);
- pmd = READ_ONCE(*pmdp);
- /*
- * A hugepage collapse is captured by pmd_none, because
- * it mark the pmd none and do a hpte invalidate.
- */
- if (pmd_none(pmd))
- return NULL;
-
- if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
- if (is_thp)
- *is_thp = true;
- ret_pte = (pte_t *) pmdp;
- goto out;
- }
- /*
- * pmd_large check below will handle the swap pmd pte
- * we need to do both the check because they are config
- * dependent.
- */
- if (pmd_huge(pmd) || pmd_large(pmd)) {
- ret_pte = (pte_t *) pmdp;
- goto out;
- } else if (is_hugepd(__hugepd(pmd_val(pmd))))
- hpdp = (hugepd_t *)&pmd;
- else
- return pte_offset_kernel(&pmd, ea);
- }
- }
- if (!hpdp)
- return NULL;
-
- ret_pte = hugepte_offset(*hpdp, ea, pdshift);
- pdshift = hugepd_shift(*hpdp);
-out:
- if (hpage_shift)
- *hpage_shift = pdshift;
- return ret_pte;
-}
-EXPORT_SYMBOL_GPL(__find_linux_pte);
-
int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index d3d61d29b4f1..9f4ccd15849f 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -30,6 +30,7 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
+#include <asm/hugetlb.h>

static inline int is_exec_fault(void)
{
@@ -299,3 +300,106 @@ unsigned long vmalloc_to_phys(void *va)
return __pa(pfn_to_kaddr(pfn)) + offset_in_page(va);
}
EXPORT_SYMBOL_GPL(vmalloc_to_phys);
+
+/*
+ * We have 4 cases for pgds and pmds:
+ * (1) invalid (all zeroes)
+ * (2) pointer to next table, as normal; bottom 6 bits == 0
+ * (3) leaf pte for huge page _PAGE_PTE set
+ * (4) hugepd pointer, _PAGE_PTE = 0 and bits [2..6] indicate size of table
+ *
+ * So long as we atomically load page table pointers we are safe against teardown,
+ * we can follow the address down to the the page and take a ref on it.
+ * This function need to be called with interrupts disabled. We use this variant
+ * when we have MSR[EE] = 0 but the paca->irq_soft_mask = IRQS_ENABLED
+ */
+pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
+ bool *is_thp, unsigned *hpage_shift)
+{
+ pgd_t pgd, *pgdp;
+ pud_t pud, *pudp;
+ pmd_t pmd, *pmdp;
+ pte_t *ret_pte;
+ hugepd_t *hpdp = NULL;
+ unsigned pdshift = PGDIR_SHIFT;
+
+ if (hpage_shift)
+ *hpage_shift = 0;
+
+ if (is_thp)
+ *is_thp = false;
+
+ pgdp = pgdir + pgd_index(ea);
+ pgd = READ_ONCE(*pgdp);
+ /*
+ * Always operate on the local stack value. This make sure the
+ * value don't get updated by a parallel THP split/collapse,
+ * page fault or a page unmap. The return pte_t * is still not
+ * stable. So should be checked there for above conditions.
+ */
+ if (pgd_none(pgd))
+ return NULL;
+ else if (pgd_huge(pgd)) {
+ ret_pte = (pte_t *) pgdp;
+ goto out;
+ } else if (is_hugepd(__hugepd(pgd_val(pgd))))
+ hpdp = (hugepd_t *)&pgd;
+ else {
+ /*
+ * Even if we end up with an unmap, the pgtable will not
+ * be freed, because we do an rcu free and here we are
+ * irq disabled
+ */
+ pdshift = PUD_SHIFT;
+ pudp = pud_offset(&pgd, ea);
+ pud = READ_ONCE(*pudp);
+
+ if (pud_none(pud))
+ return NULL;
+ else if (pud_huge(pud)) {
+ ret_pte = (pte_t *) pudp;
+ goto out;
+ } else if (is_hugepd(__hugepd(pud_val(pud))))
+ hpdp = (hugepd_t *)&pud;
+ else {
+ pdshift = PMD_SHIFT;
+ pmdp = pmd_offset(&pud, ea);
+ pmd = READ_ONCE(*pmdp);
+ /*
+ * A hugepage collapse is captured by pmd_none, because
+ * it mark the pmd none and do a hpte invalidate.
+ */
+ if (pmd_none(pmd))
+ return NULL;
+
+ if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
+ if (is_thp)
+ *is_thp = true;
+ ret_pte = (pte_t *) pmdp;
+ goto out;
+ }
+ /*
+ * pmd_large check below will handle the swap pmd pte
+ * we need to do both the check because they are config
+ * dependent.
+ */
+ if (pmd_huge(pmd) || pmd_large(pmd)) {
+ ret_pte = (pte_t *) pmdp;
+ goto out;
+ } else if (is_hugepd(__hugepd(pmd_val(pmd))))
+ hpdp = (hugepd_t *)&pmd;
+ else
+ return pte_offset_kernel(&pmd, ea);
+ }
+ }
+ if (!hpdp)
+ return NULL;
+
+ ret_pte = hugepte_offset(*hpdp, ea, pdshift);
+ pdshift = hugepd_shift(*hpdp);
+out:
+ if (hpage_shift)
+ *hpage_shift = pdshift;
+ return ret_pte;
+}
+EXPORT_SYMBOL_GPL(__find_linux_pte);
--
2.13.3


2019-03-20 10:10:19

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 05/27] powerpc/mm: drop slice_set_user_psize()

slice_set_user_psize() is not used anymore, drop it.

Fixes: 1753dd183036 ("powerpc/mm/slice: Simplify and optimise slice context initialisation")
Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/book3s/64/slice.h | 5 -----
arch/powerpc/include/asm/nohash/64/slice.h | 1 -
2 files changed, 6 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h
index db0dedab65ee..af498b0da21a 100644
--- a/arch/powerpc/include/asm/book3s/64/slice.h
+++ b/arch/powerpc/include/asm/book3s/64/slice.h
@@ -16,11 +16,6 @@
#else /* CONFIG_PPC_MM_SLICES */

#define get_slice_psize(mm, addr) ((mm)->context.user_psize)
-#define slice_set_user_psize(mm, psize) \
-do { \
- (mm)->context.user_psize = (psize); \
- (mm)->context.sllp = SLB_VSID_USER | mmu_psize_defs[(psize)].sllp; \
-} while (0)

#endif /* CONFIG_PPC_MM_SLICES */

diff --git a/arch/powerpc/include/asm/nohash/64/slice.h b/arch/powerpc/include/asm/nohash/64/slice.h
index ad0d6e3cc1c5..1a32d1fae6af 100644
--- a/arch/powerpc/include/asm/nohash/64/slice.h
+++ b/arch/powerpc/include/asm/nohash/64/slice.h
@@ -7,6 +7,5 @@
#else /* CONFIG_PPC_64K_PAGES */
#define get_slice_psize(mm, addr) MMU_PAGE_4K
#endif /* !CONFIG_PPC_64K_PAGES */
-#define slice_set_user_psize(mm, psize) do { BUG(); } while (0)

#endif /* _ASM_POWERPC_NOHASH_64_SLICE_H */
--
2.13.3


2019-03-20 10:10:20

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 22/27] powerpc/mm: move slice_mask_for_size() into mmu.h

Move slice_mask_for_size() into subarch mmu.h

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/book3s/64/mmu.h | 22 +++++++++++++----
arch/powerpc/include/asm/nohash/32/mmu-8xx.h | 18 ++++++++++++++
arch/powerpc/mm/slice.c | 36 ----------------------------
3 files changed, 36 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
index 1ceee000c18d..927e3714b0d8 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -123,7 +123,6 @@ typedef struct {
/* NPU NMMU context */
struct npu_context *npu_context;

-#ifdef CONFIG_PPC_MM_SLICES
/* SLB page size encodings*/
unsigned char low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE];
unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
@@ -136,9 +135,6 @@ typedef struct {
struct slice_mask mask_16m;
struct slice_mask mask_16g;
# endif
-#else
- u16 sllp; /* SLB page size encoding */
-#endif
unsigned long vdso_base;
#ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
@@ -172,6 +168,24 @@ extern int mmu_vmalloc_psize;
extern int mmu_vmemmap_psize;
extern int mmu_io_psize;

+static inline struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
+{
+#ifdef CONFIG_PPC_64K_PAGES
+ if (psize == MMU_PAGE_64K)
+ return &ctx->mask_64k;
+#endif
+ if (psize == MMU_PAGE_4K)
+ return &ctx->mask_4k;
+#ifdef CONFIG_HUGETLB_PAGE
+ if (psize == MMU_PAGE_16M)
+ return &ctx->mask_16m;
+ if (psize == MMU_PAGE_16G)
+ return &ctx->mask_16g;
+#endif
+ WARN_ON(true);
+ return NULL;
+}
+
/* MMU initialization */
void mmu_early_init_devtree(void);
void hash__early_init_devtree(void);
diff --git a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
index 0a1a3fc54e54..4ba92c48b3a5 100644
--- a/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
@@ -255,4 +255,22 @@ extern s32 patch__itlbmiss_perf, patch__dtlbmiss_perf;

#define mmu_linear_psize MMU_PAGE_8M

+#ifndef __ASSEMBLY__
+#ifdef CONFIG_PPC_MM_SLICES
+static inline struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
+{
+ if (psize == mmu_virtual_psize)
+ return &ctx->mask_base_psize;
+#ifdef CONFIG_HUGETLB_PAGE
+ if (psize == MMU_PAGE_512K)
+ return &ctx->mask_512k;
+ if (psize == MMU_PAGE_8M)
+ return &ctx->mask_8m;
+#endif
+ WARN_ON(true);
+ return NULL;
+}
+#endif
+#endif /* !__ASSEMBLY__ */
+
#endif /* _ASM_POWERPC_MMU_8XX_H_ */
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 231fd88d97e2..357d64e14757 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -126,42 +126,6 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret,
__set_bit(i, ret->high_slices);
}

-#ifdef CONFIG_PPC_BOOK3S_64
-static struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
-{
-#ifdef CONFIG_PPC_64K_PAGES
- if (psize == MMU_PAGE_64K)
- return &ctx->mask_64k;
-#endif
- if (psize == MMU_PAGE_4K)
- return &ctx->mask_4k;
-#ifdef CONFIG_HUGETLB_PAGE
- if (psize == MMU_PAGE_16M)
- return &ctx->mask_16m;
- if (psize == MMU_PAGE_16G)
- return &ctx->mask_16g;
-#endif
- WARN_ON(true);
- return NULL;
-}
-#elif defined(CONFIG_PPC_8xx)
-static struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
-{
- if (psize == mmu_virtual_psize)
- return &ctx->mask_base_psize;
-#ifdef CONFIG_HUGETLB_PAGE
- if (psize == MMU_PAGE_512K)
- return &ctx->mask_512k;
- if (psize == MMU_PAGE_8M)
- return &ctx->mask_8m;
-#endif
- WARN_ON(true);
- return NULL;
-}
-#else
-#error "Must define the slice masks for page sizes supported by the platform"
-#endif
-
static bool slice_check_range_fits(struct mm_struct *mm,
const struct slice_mask *available,
unsigned long start, unsigned long len)
--
2.13.3


2019-03-20 10:10:20

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 09/27] powerpc/mm: make hugetlbpage.c depend on CONFIG_HUGETLB_PAGE

The only function in hugetlbpage.c which doesn't depend on
CONFIG_HUGETLB_PAGE is gup_hugepte(), and this function is
only called from gup_huge_pd() which depends on
CONFIG_HUGETLB_PAGE so all the content of hugetlbpage.c
depends on CONFIG_HUGETLB_PAGE.

This patch modifies Makefile to only compile hugetlbpage.c
when CONFIG_HUGETLB_PAGE is set.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/Makefile | 2 +-
arch/powerpc/mm/hugetlbpage.c | 5 -----
2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 2c23d1ece034..20b900537fc9 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o
obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
obj-$(CONFIG_PPC_SPLPAR) += vphn.o
obj-$(CONFIG_PPC_MM_SLICES) += slice.o
-obj-y += hugetlbpage.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
ifdef CONFIG_HUGETLB_PAGE
obj-$(CONFIG_PPC_BOOK3S_64) += hugetlbpage-hash64.o
obj-$(CONFIG_PPC_RADIX_MMU) += hugetlbpage-radix.o
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 202ae006aa39..6d9751b188c1 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -26,9 +26,6 @@
#include <asm/hugetlb.h>
#include <asm/pte-walk.h>

-
-#ifdef CONFIG_HUGETLB_PAGE
-
#define PAGE_SHIFT_64K 16
#define PAGE_SHIFT_512K 19
#define PAGE_SHIFT_8M 23
@@ -757,8 +754,6 @@ void flush_dcache_icache_hugepage(struct page *page)
}
}

-#endif /* CONFIG_HUGETLB_PAGE */
-
int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
unsigned long end, int write, struct page **pages, int *nr)
{
--
2.13.3


2019-03-20 10:10:27

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 01/27] powerpc/mm: Don't BUG() in hugepd_page()

Don't BUG(), just warn and return NULL.
If the NULL value is not handled, it will get catched anyway.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/hugetlb.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 8d40565ad0c3..48c29686c78e 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -14,7 +14,8 @@
*/
static inline pte_t *hugepd_page(hugepd_t hpd)
{
- BUG_ON(!hugepd_ok(hpd));
+ if (WARN_ON(!hugepd_ok(hpd)))
+ return NULL;
/*
* We have only four bits to encode, MMU page size
*/
@@ -42,7 +43,8 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,

static inline pte_t *hugepd_page(hugepd_t hpd)
{
- BUG_ON(!hugepd_ok(hpd));
+ if (WARN_ON(!hugepd_ok(hpd)))
+ return NULL;
#ifdef CONFIG_PPC_8xx
return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
#else
--
2.13.3


2019-03-20 10:11:00

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 11/27] powerpc/mm: split asm/hugetlb.h into dedicated subarch files

Three subarches support hugepages:
- fsl book3e
- book3s/64
- 8xx

This patch splits asm/hugetlb.h to reduce the #ifdef mess.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/book3s/64/hugetlb.h | 41 +++++++++++
arch/powerpc/include/asm/hugetlb.h | 89 ++----------------------
arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 32 +++++++++
arch/powerpc/include/asm/nohash/hugetlb-book3e.h | 31 +++++++++
4 files changed, 108 insertions(+), 85 deletions(-)
create mode 100644 arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
create mode 100644 arch/powerpc/include/asm/nohash/hugetlb-book3e.h

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index ec2a55a553c7..2f9cf2bc601c 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -62,4 +62,45 @@ extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
extern void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t old_pte, pte_t new_pte);
+/*
+ * This should work for other subarchs too. But right now we use the
+ * new format only for 64bit book3s
+ */
+static inline pte_t *hugepd_page(hugepd_t hpd)
+{
+ if (WARN_ON(!hugepd_ok(hpd)))
+ return NULL;
+ /*
+ * We have only four bits to encode, MMU page size
+ */
+ BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
+ return __va(hpd_val(hpd) & HUGEPD_ADDR_MASK);
+}
+
+static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
+{
+ return (hpd_val(hpd) & HUGEPD_SHIFT_MASK) >> 2;
+}
+
+static inline unsigned int hugepd_shift(hugepd_t hpd)
+{
+ return mmu_psize_to_shift(hugepd_mmu_psize(hpd));
+}
+static inline void flush_hugetlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+ if (radix_enabled())
+ return radix__flush_hugetlb_page(vma, vmaddr);
+}
+
+static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
+ unsigned int pdshift)
+{
+ unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd);
+
+ return hugepd_page(hpd) + idx;
+}
+
+void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+
#endif
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 48c29686c78e..fd5c0873a57d 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -6,85 +6,13 @@
#include <asm/page.h>

#ifdef CONFIG_PPC_BOOK3S_64
-
#include <asm/book3s/64/hugetlb.h>
-/*
- * This should work for other subarchs too. But right now we use the
- * new format only for 64bit book3s
- */
-static inline pte_t *hugepd_page(hugepd_t hpd)
-{
- if (WARN_ON(!hugepd_ok(hpd)))
- return NULL;
- /*
- * We have only four bits to encode, MMU page size
- */
- BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
- return __va(hpd_val(hpd) & HUGEPD_ADDR_MASK);
-}
-
-static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
-{
- return (hpd_val(hpd) & HUGEPD_SHIFT_MASK) >> 2;
-}
-
-static inline unsigned int hugepd_shift(hugepd_t hpd)
-{
- return mmu_psize_to_shift(hugepd_mmu_psize(hpd));
-}
-static inline void flush_hugetlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
- if (radix_enabled())
- return radix__flush_hugetlb_page(vma, vmaddr);
-}
-
-#else
-
-static inline pte_t *hugepd_page(hugepd_t hpd)
-{
- if (WARN_ON(!hugepd_ok(hpd)))
- return NULL;
-#ifdef CONFIG_PPC_8xx
- return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
-#else
- return (pte_t *)((hpd_val(hpd) &
- ~HUGEPD_SHIFT_MASK) | PD_HUGE);
-#endif
-}
-
-static inline unsigned int hugepd_shift(hugepd_t hpd)
-{
-#ifdef CONFIG_PPC_8xx
- return ((hpd_val(hpd) & _PMD_PAGE_MASK) >> 1) + 17;
-#else
- return hpd_val(hpd) & HUGEPD_SHIFT_MASK;
-#endif
-}
-
+#elif defined(CONFIG_PPC_FSL_BOOK3E)
+#include <asm/nohash/hugetlb-book3e.h>
+#elif defined(CONFIG_PPC_8xx)
+#include <asm/nohash/32/hugetlb-8xx.h>
#endif /* CONFIG_PPC_BOOK3S_64 */

-
-static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
- unsigned pdshift)
-{
- /*
- * On FSL BookE, we have multiple higher-level table entries that
- * point to the same hugepte. Just use the first one since they're all
- * identical. So for that case, idx=0.
- */
- unsigned long idx = 0;
-
- pte_t *dir = hugepd_page(hpd);
-#ifdef CONFIG_PPC_8xx
- idx = (addr & ((1UL << pdshift) - 1)) >> PAGE_SHIFT;
-#elif !defined(CONFIG_PPC_FSL_BOOK3E)
- idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd);
-#endif
-
- return dir + idx;
-}
-
void flush_dcache_icache_hugepage(struct page *page);

int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
@@ -101,15 +29,6 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,

void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
pte_t pte);
-#ifdef CONFIG_PPC_8xx
-static inline void flush_hugetlb_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
- flush_tlb_page(vma, vmaddr);
-}
-#else
-void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
-#endif

#define __HAVE_ARCH_HUGETLB_FREE_PGD_RANGE
void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
new file mode 100644
index 000000000000..209e6a219835
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H
+#define _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H
+
+static inline pte_t *hugepd_page(hugepd_t hpd)
+{
+ if (WARN_ON(!hugepd_ok(hpd)))
+ return NULL;
+
+ return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
+}
+
+static inline unsigned int hugepd_shift(hugepd_t hpd)
+{
+ return ((hpd_val(hpd) & _PMD_PAGE_MASK) >> 1) + 17;
+}
+
+static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
+ unsigned int pdshift)
+{
+ unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> PAGE_SHIFT;
+
+ return hugepd_page(hpd) + idx;
+}
+
+static inline void flush_hugetlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+ flush_tlb_page(vma, vmaddr);
+}
+
+#endif /* _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H */
diff --git a/arch/powerpc/include/asm/nohash/hugetlb-book3e.h b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
new file mode 100644
index 000000000000..e94f1cd048ee
--- /dev/null
+++ b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H
+#define _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H
+
+static inline pte_t *hugepd_page(hugepd_t hpd)
+{
+ if (WARN_ON(!hugepd_ok(hpd)))
+ return NULL;
+
+ return (pte_t *)((hpd_val(hpd) & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
+}
+
+static inline unsigned int hugepd_shift(hugepd_t hpd)
+{
+ return hpd_val(hpd) & HUGEPD_SHIFT_MASK;
+}
+
+static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
+ unsigned int pdshift)
+{
+ /*
+ * On FSL BookE, we have multiple higher-level table entries that
+ * point to the same hugepte. Just use the first one since they're all
+ * identical. So for that case, idx=0.
+ */
+ return hugepd_page(hpd);
+}
+
+void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+
+#endif /* _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H */
--
2.13.3


2019-03-20 10:11:52

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH v1 03/27] powerpc/mm: don't BUG() in slice_mask_for_size()

When no mask is found for the page size, WARN() and return NULL
instead of BUG()ing.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/mm/slice.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index aec91dbcdc0b..011d470ea340 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -165,7 +165,8 @@ static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
if (psize == MMU_PAGE_16G)
return &mm->context.mask_16g;
#endif
- BUG();
+ WARN_ON(true);
+ return NULL;
}
#elif defined(CONFIG_PPC_8xx)
static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
@@ -178,7 +179,8 @@ static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
if (psize == MMU_PAGE_8M)
return &mm->context.mask_8m;
#endif
- BUG();
+ WARN_ON(true);
+ return NULL;
}
#else
#error "Must define the slice masks for page sizes supported by the platform"
--
2.13.3


2019-03-21 10:45:08

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v1 11/27] powerpc/mm: split asm/hugetlb.h into dedicated subarch files

snowpatch fails applying this.

I usually base my patches on branch merge. Shouldn't snowpatch use merge
branch as well instead of next branch ?

Christophe

Le 20/03/2019 à 11:06, Christophe Leroy a écrit :
> Three subarches support hugepages:
> - fsl book3e
> - book3s/64
> - 8xx
>
> This patch splits asm/hugetlb.h to reduce the #ifdef mess.
>
> Signed-off-by: Christophe Leroy <[email protected]>
> ---
> arch/powerpc/include/asm/book3s/64/hugetlb.h | 41 +++++++++++
> arch/powerpc/include/asm/hugetlb.h | 89 ++----------------------
> arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 32 +++++++++
> arch/powerpc/include/asm/nohash/hugetlb-book3e.h | 31 +++++++++
> 4 files changed, 108 insertions(+), 85 deletions(-)
> create mode 100644 arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> create mode 100644 arch/powerpc/include/asm/nohash/hugetlb-book3e.h
>
> diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
> index ec2a55a553c7..2f9cf2bc601c 100644
> --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
> +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
> @@ -62,4 +62,45 @@ extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
> extern void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
> unsigned long addr, pte_t *ptep,
> pte_t old_pte, pte_t new_pte);
> +/*
> + * This should work for other subarchs too. But right now we use the
> + * new format only for 64bit book3s
> + */
> +static inline pte_t *hugepd_page(hugepd_t hpd)
> +{
> + if (WARN_ON(!hugepd_ok(hpd)))
> + return NULL;
> + /*
> + * We have only four bits to encode, MMU page size
> + */
> + BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
> + return __va(hpd_val(hpd) & HUGEPD_ADDR_MASK);
> +}
> +
> +static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
> +{
> + return (hpd_val(hpd) & HUGEPD_SHIFT_MASK) >> 2;
> +}
> +
> +static inline unsigned int hugepd_shift(hugepd_t hpd)
> +{
> + return mmu_psize_to_shift(hugepd_mmu_psize(hpd));
> +}
> +static inline void flush_hugetlb_page(struct vm_area_struct *vma,
> + unsigned long vmaddr)
> +{
> + if (radix_enabled())
> + return radix__flush_hugetlb_page(vma, vmaddr);
> +}
> +
> +static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
> + unsigned int pdshift)
> +{
> + unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd);
> +
> + return hugepd_page(hpd) + idx;
> +}
> +
> +void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
> +
> #endif
> diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
> index 48c29686c78e..fd5c0873a57d 100644
> --- a/arch/powerpc/include/asm/hugetlb.h
> +++ b/arch/powerpc/include/asm/hugetlb.h
> @@ -6,85 +6,13 @@
> #include <asm/page.h>
>
> #ifdef CONFIG_PPC_BOOK3S_64
> -
> #include <asm/book3s/64/hugetlb.h>
> -/*
> - * This should work for other subarchs too. But right now we use the
> - * new format only for 64bit book3s
> - */
> -static inline pte_t *hugepd_page(hugepd_t hpd)
> -{
> - if (WARN_ON(!hugepd_ok(hpd)))
> - return NULL;
> - /*
> - * We have only four bits to encode, MMU page size
> - */
> - BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf);
> - return __va(hpd_val(hpd) & HUGEPD_ADDR_MASK);
> -}
> -
> -static inline unsigned int hugepd_mmu_psize(hugepd_t hpd)
> -{
> - return (hpd_val(hpd) & HUGEPD_SHIFT_MASK) >> 2;
> -}
> -
> -static inline unsigned int hugepd_shift(hugepd_t hpd)
> -{
> - return mmu_psize_to_shift(hugepd_mmu_psize(hpd));
> -}
> -static inline void flush_hugetlb_page(struct vm_area_struct *vma,
> - unsigned long vmaddr)
> -{
> - if (radix_enabled())
> - return radix__flush_hugetlb_page(vma, vmaddr);
> -}
> -
> -#else
> -
> -static inline pte_t *hugepd_page(hugepd_t hpd)
> -{
> - if (WARN_ON(!hugepd_ok(hpd)))
> - return NULL;
> -#ifdef CONFIG_PPC_8xx
> - return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
> -#else
> - return (pte_t *)((hpd_val(hpd) &
> - ~HUGEPD_SHIFT_MASK) | PD_HUGE);
> -#endif
> -}
> -
> -static inline unsigned int hugepd_shift(hugepd_t hpd)
> -{
> -#ifdef CONFIG_PPC_8xx
> - return ((hpd_val(hpd) & _PMD_PAGE_MASK) >> 1) + 17;
> -#else
> - return hpd_val(hpd) & HUGEPD_SHIFT_MASK;
> -#endif
> -}
> -
> +#elif defined(CONFIG_PPC_FSL_BOOK3E)
> +#include <asm/nohash/hugetlb-book3e.h>
> +#elif defined(CONFIG_PPC_8xx)
> +#include <asm/nohash/32/hugetlb-8xx.h>
> #endif /* CONFIG_PPC_BOOK3S_64 */
>
> -
> -static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
> - unsigned pdshift)
> -{
> - /*
> - * On FSL BookE, we have multiple higher-level table entries that
> - * point to the same hugepte. Just use the first one since they're all
> - * identical. So for that case, idx=0.
> - */
> - unsigned long idx = 0;
> -
> - pte_t *dir = hugepd_page(hpd);
> -#ifdef CONFIG_PPC_8xx
> - idx = (addr & ((1UL << pdshift) - 1)) >> PAGE_SHIFT;
> -#elif !defined(CONFIG_PPC_FSL_BOOK3E)
> - idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd);
> -#endif
> -
> - return dir + idx;
> -}
> -
> void flush_dcache_icache_hugepage(struct page *page);
>
> int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
> @@ -101,15 +29,6 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
>
> void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
> pte_t pte);
> -#ifdef CONFIG_PPC_8xx
> -static inline void flush_hugetlb_page(struct vm_area_struct *vma,
> - unsigned long vmaddr)
> -{
> - flush_tlb_page(vma, vmaddr);
> -}
> -#else
> -void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
> -#endif
>
> #define __HAVE_ARCH_HUGETLB_FREE_PGD_RANGE
> void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
> diff --git a/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> new file mode 100644
> index 000000000000..209e6a219835
> --- /dev/null
> +++ b/arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H
> +#define _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H
> +
> +static inline pte_t *hugepd_page(hugepd_t hpd)
> +{
> + if (WARN_ON(!hugepd_ok(hpd)))
> + return NULL;
> +
> + return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
> +}
> +
> +static inline unsigned int hugepd_shift(hugepd_t hpd)
> +{
> + return ((hpd_val(hpd) & _PMD_PAGE_MASK) >> 1) + 17;
> +}
> +
> +static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
> + unsigned int pdshift)
> +{
> + unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> PAGE_SHIFT;
> +
> + return hugepd_page(hpd) + idx;
> +}
> +
> +static inline void flush_hugetlb_page(struct vm_area_struct *vma,
> + unsigned long vmaddr)
> +{
> + flush_tlb_page(vma, vmaddr);
> +}
> +
> +#endif /* _ASM_POWERPC_NOHASH_32_HUGETLB_8XX_H */
> diff --git a/arch/powerpc/include/asm/nohash/hugetlb-book3e.h b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
> new file mode 100644
> index 000000000000..e94f1cd048ee
> --- /dev/null
> +++ b/arch/powerpc/include/asm/nohash/hugetlb-book3e.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H
> +#define _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H
> +
> +static inline pte_t *hugepd_page(hugepd_t hpd)
> +{
> + if (WARN_ON(!hugepd_ok(hpd)))
> + return NULL;
> +
> + return (pte_t *)((hpd_val(hpd) & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
> +}
> +
> +static inline unsigned int hugepd_shift(hugepd_t hpd)
> +{
> + return hpd_val(hpd) & HUGEPD_SHIFT_MASK;
> +}
> +
> +static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
> + unsigned int pdshift)
> +{
> + /*
> + * On FSL BookE, we have multiple higher-level table entries that
> + * point to the same hugepte. Just use the first one since they're all
> + * identical. So for that case, idx=0.
> + */
> + return hugepd_page(hpd);
> +}
> +
> +void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
> +
> +#endif /* _ASM_POWERPC_NOHASH_HUGETLB_BOOK3E_H */
>

2019-03-21 10:45:58

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v1 00/27] Reduce ifdef mess in hugetlbpage.c and slice.c

This series went through a successfull build test on kisskb:

http://kisskb.ellerman.id.au/kisskb/branch/chleroy/head/f9dc3b2203af4356e9eac2d901126a0dfc5b51f6/

Christophe

Le 20/03/2019 à 11:06, Christophe Leroy a écrit :
> The main purpose of this series is to reduce the amount of #ifdefs in
> hugetlbpage.c and slice.c
>
> At the same time, it does some cleanup by reducing the number of BUG_ON()
> and dropping unused functions.
>
> It also removes 64k pages related code in nohash/64 as 64k pages are
> can only by selected on book3s/64
>
> Christophe Leroy (27):
> powerpc/mm: Don't BUG() in hugepd_page()
> powerpc/mm: don't BUG in add_huge_page_size()
> powerpc/mm: don't BUG() in slice_mask_for_size()
> powerpc/book3e: drop mmu_get_tsize()
> powerpc/mm: drop slice_set_user_psize()
> powerpc/64: only book3s/64 supports CONFIG_PPC_64K_PAGES
> powerpc/book3e: hugetlbpage is only for CONFIG_PPC_FSL_BOOK3E
> powerpc/mm: move __find_linux_pte() out of hugetlbpage.c
> powerpc/mm: make hugetlbpage.c depend on CONFIG_HUGETLB_PAGE
> powerpc/mm: make gup_hugepte() static
> powerpc/mm: split asm/hugetlb.h into dedicated subarch files
> powerpc/mm: add a helper to populate hugepd
> powerpc/mm: define get_slice_psize() all the time
> powerpc/mm: no slice for nohash/64
> powerpc/mm: cleanup ifdef mess in add_huge_page_size()
> powerpc/mm: move hugetlb_disabled into asm/hugetlb.h
> powerpc/mm: cleanup HPAGE_SHIFT setup
> powerpc/mm: cleanup remaining ifdef mess in hugetlbpage.c
> powerpc/mm: drop slice DEBUG
> powerpc/mm: remove unnecessary #ifdef CONFIG_PPC64
> powerpc/mm: hand a context_t over to slice_mask_for_size() instead of
> mm_struct
> powerpc/mm: move slice_mask_for_size() into mmu.h
> powerpc/mm: remove a couple of #ifdef CONFIG_PPC_64K_PAGES in
> mm/slice.c
> powerpc: define subarch SLB_ADDR_LIMIT_DEFAULT
> powerpc/mm: flatten function __find_linux_pte()
> powerpc/mm: flatten function __find_linux_pte() step 2
> powerpc/mm: flatten function __find_linux_pte() step 3
>
> arch/powerpc/Kconfig | 3 +-
> arch/powerpc/include/asm/book3s/64/hugetlb.h | 73 +++++++
> arch/powerpc/include/asm/book3s/64/mmu.h | 22 +-
> arch/powerpc/include/asm/book3s/64/slice.h | 7 +-
> arch/powerpc/include/asm/hugetlb.h | 87 +-------
> arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h | 45 +++++
> arch/powerpc/include/asm/nohash/32/mmu-8xx.h | 18 ++
> arch/powerpc/include/asm/nohash/32/slice.h | 2 +
> arch/powerpc/include/asm/nohash/64/pgalloc.h | 3 -
> arch/powerpc/include/asm/nohash/64/pgtable.h | 4 -
> arch/powerpc/include/asm/nohash/64/slice.h | 12 --
> arch/powerpc/include/asm/nohash/hugetlb-book3e.h | 45 +++++
> arch/powerpc/include/asm/nohash/pte-book3e.h | 5 -
> arch/powerpc/include/asm/page.h | 12 +-
> arch/powerpc/include/asm/pgtable-be-types.h | 7 +-
> arch/powerpc/include/asm/pgtable-types.h | 7 +-
> arch/powerpc/include/asm/pgtable.h | 3 -
> arch/powerpc/include/asm/slice.h | 8 +-
> arch/powerpc/include/asm/task_size_64.h | 2 +-
> arch/powerpc/kernel/fadump.c | 1 +
> arch/powerpc/kernel/setup-common.c | 8 +-
> arch/powerpc/mm/Makefile | 4 +-
> arch/powerpc/mm/hash_utils_64.c | 1 +
> arch/powerpc/mm/hugetlbpage-book3e.c | 52 ++---
> arch/powerpc/mm/hugetlbpage-hash64.c | 16 ++
> arch/powerpc/mm/hugetlbpage.c | 245 ++++-------------------
> arch/powerpc/mm/pgtable.c | 114 +++++++++++
> arch/powerpc/mm/slice.c | 132 ++----------
> arch/powerpc/mm/tlb_low_64e.S | 31 ---
> arch/powerpc/mm/tlb_nohash.c | 13 --
> arch/powerpc/platforms/Kconfig.cputype | 4 +
> 31 files changed, 438 insertions(+), 548 deletions(-)
> create mode 100644 arch/powerpc/include/asm/nohash/32/hugetlb-8xx.h
> delete mode 100644 arch/powerpc/include/asm/nohash/64/slice.h
> create mode 100644 arch/powerpc/include/asm/nohash/hugetlb-book3e.h
>

2019-04-11 05:41:34

by Aneesh Kumar K.V

[permalink] [raw]
Subject: Re: [PATCH v1 01/27] powerpc/mm: Don't BUG() in hugepd_page()

Christophe Leroy <[email protected]> writes:

> Don't BUG(), just warn and return NULL.
> If the NULL value is not handled, it will get catched anyway.
>
> Signed-off-by: Christophe Leroy <[email protected]>
> ---
> arch/powerpc/include/asm/hugetlb.h | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
> index 8d40565ad0c3..48c29686c78e 100644
> --- a/arch/powerpc/include/asm/hugetlb.h
> +++ b/arch/powerpc/include/asm/hugetlb.h
> @@ -14,7 +14,8 @@
> */
> static inline pte_t *hugepd_page(hugepd_t hpd)
> {
> - BUG_ON(!hugepd_ok(hpd));
> + if (WARN_ON(!hugepd_ok(hpd)))
> + return NULL;

We should not find that true. That BUG_ON was there to catch errors
when changing pte formats. May be switch that VM_BUG_ON()?

> /*
> * We have only four bits to encode, MMU page size
> */
> @@ -42,7 +43,8 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
>
> static inline pte_t *hugepd_page(hugepd_t hpd)
> {
> - BUG_ON(!hugepd_ok(hpd));
> + if (WARN_ON(!hugepd_ok(hpd)))
> + return NULL;
> #ifdef CONFIG_PPC_8xx
> return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
> #else
> --
> 2.13.3

2019-04-11 05:42:20

by Aneesh Kumar K.V

[permalink] [raw]
Subject: Re: [PATCH v1 02/27] powerpc/mm: don't BUG in add_huge_page_size()

Christophe Leroy <[email protected]> writes:

> No reason to BUG() in add_huge_page_size(). Just WARN and
> reject the add.
>
> Signed-off-by: Christophe Leroy <[email protected]>
> ---
> arch/powerpc/mm/hugetlbpage.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
> index 9e732bb2c84a..cf2978e235f3 100644
> --- a/arch/powerpc/mm/hugetlbpage.c
> +++ b/arch/powerpc/mm/hugetlbpage.c
> @@ -634,7 +634,8 @@ static int __init add_huge_page_size(unsigned long long size)
> }
> #endif
>
> - BUG_ON(mmu_psize_defs[mmu_psize].shift != shift);
> + if (WARN_ON(mmu_psize_defs[mmu_psize].shift != shift))
> + return -EINVAL;

Same here. There are not catching runtime errors. We should never find
that true. This is to catch mistakes during development changes. Switch
to VM_BUG_ON?


>
> /* Return if huge page size has already been setup */
> if (size_to_hstate(size))
> --
> 2.13.3

2019-04-11 05:43:11

by Aneesh Kumar K.V

[permalink] [raw]
Subject: Re: [PATCH v1 03/27] powerpc/mm: don't BUG() in slice_mask_for_size()

Christophe Leroy <[email protected]> writes:

> When no mask is found for the page size, WARN() and return NULL
> instead of BUG()ing.
>
> Signed-off-by: Christophe Leroy <[email protected]>
> ---
> arch/powerpc/mm/slice.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
> index aec91dbcdc0b..011d470ea340 100644
> --- a/arch/powerpc/mm/slice.c
> +++ b/arch/powerpc/mm/slice.c
> @@ -165,7 +165,8 @@ static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
> if (psize == MMU_PAGE_16G)
> return &mm->context.mask_16g;
> #endif
> - BUG();
> + WARN_ON(true);
> + return NULL;
> }


Same here. There are not catching runtime errors. We should never find
that true. This is to catch mistakes during development changes. Switch
to VM_BUG_ON?


> #elif defined(CONFIG_PPC_8xx)
> static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
> @@ -178,7 +179,8 @@ static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
> if (psize == MMU_PAGE_8M)
> return &mm->context.mask_8m;
> #endif
> - BUG();
> + WARN_ON(true);
> + return NULL;
> }
> #else
> #error "Must define the slice masks for page sizes supported by the platform"
> --
> 2.13.3

2019-04-24 14:14:25

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v1 03/27] powerpc/mm: don't BUG() in slice_mask_for_size()



Le 11/04/2019 à 07:41, Aneesh Kumar K.V a écrit :
> Christophe Leroy <[email protected]> writes:
>
>> When no mask is found for the page size, WARN() and return NULL
>> instead of BUG()ing.
>>
>> Signed-off-by: Christophe Leroy <[email protected]>
>> ---
>> arch/powerpc/mm/slice.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
>> index aec91dbcdc0b..011d470ea340 100644
>> --- a/arch/powerpc/mm/slice.c
>> +++ b/arch/powerpc/mm/slice.c
>> @@ -165,7 +165,8 @@ static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
>> if (psize == MMU_PAGE_16G)
>> return &mm->context.mask_16g;
>> #endif
>> - BUG();
>> + WARN_ON(true);
>> + return NULL;
>> }
>
>
> Same here. There are not catching runtime errors. We should never find
> that true. This is to catch mistakes during development changes. Switch
> to VM_BUG_ON?

Ok, I'll switch to VM_BUG_ON()

Christophe

>
>
>> #elif defined(CONFIG_PPC_8xx)
>> static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
>> @@ -178,7 +179,8 @@ static struct slice_mask *slice_mask_for_size(struct mm_struct *mm, int psize)
>> if (psize == MMU_PAGE_8M)
>> return &mm->context.mask_8m;
>> #endif
>> - BUG();
>> + WARN_ON(true);
>> + return NULL;
>> }
>> #else
>> #error "Must define the slice masks for page sizes supported by the platform"
>> --
>> 2.13.3

2019-04-24 19:16:41

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v1 02/27] powerpc/mm: don't BUG in add_huge_page_size()



Le 11/04/2019 à 07:41, Aneesh Kumar K.V a écrit :
> Christophe Leroy <[email protected]> writes:
>
>> No reason to BUG() in add_huge_page_size(). Just WARN and
>> reject the add.
>>
>> Signed-off-by: Christophe Leroy <[email protected]>
>> ---
>> arch/powerpc/mm/hugetlbpage.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
>> index 9e732bb2c84a..cf2978e235f3 100644
>> --- a/arch/powerpc/mm/hugetlbpage.c
>> +++ b/arch/powerpc/mm/hugetlbpage.c
>> @@ -634,7 +634,8 @@ static int __init add_huge_page_size(unsigned long long size)
>> }
>> #endif
>>
>> - BUG_ON(mmu_psize_defs[mmu_psize].shift != shift);
>> + if (WARN_ON(mmu_psize_defs[mmu_psize].shift != shift))
>> + return -EINVAL;
>
> Same here. There are not catching runtime errors. We should never find
> that true. This is to catch mistakes during development changes. Switch
> to VM_BUG_ON?

Ok, I'll switch to VM_BUG_ON()

Christophe

>
>
>>
>> /* Return if huge page size has already been setup */
>> if (size_to_hstate(size))
>> --
>> 2.13.3

2019-04-24 19:44:01

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v1 01/27] powerpc/mm: Don't BUG() in hugepd_page()



Le 11/04/2019 à 07:39, Aneesh Kumar K.V a écrit :
> Christophe Leroy <[email protected]> writes:
>
>> Don't BUG(), just warn and return NULL.
>> If the NULL value is not handled, it will get catched anyway.
>>
>> Signed-off-by: Christophe Leroy <[email protected]>
>> ---
>> arch/powerpc/include/asm/hugetlb.h | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
>> index 8d40565ad0c3..48c29686c78e 100644
>> --- a/arch/powerpc/include/asm/hugetlb.h
>> +++ b/arch/powerpc/include/asm/hugetlb.h
>> @@ -14,7 +14,8 @@
>> */
>> static inline pte_t *hugepd_page(hugepd_t hpd)
>> {
>> - BUG_ON(!hugepd_ok(hpd));
>> + if (WARN_ON(!hugepd_ok(hpd)))
>> + return NULL;
>
> We should not find that true. That BUG_ON was there to catch errors
> when changing pte formats. May be switch that VM_BUG_ON()?

Ok, I'll switch to VM_BUG_ON()

Christophe

>
>> /*
>> * We have only four bits to encode, MMU page size
>> */
>> @@ -42,7 +43,8 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
>>
>> static inline pte_t *hugepd_page(hugepd_t hpd)
>> {
>> - BUG_ON(!hugepd_ok(hpd));
>> + if (WARN_ON(!hugepd_ok(hpd)))
>> + return NULL;
>> #ifdef CONFIG_PPC_8xx
>> return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
>> #else
>> --
>> 2.13.3