Re: [PATCH 1/2] powerpc/8xx: Refactor calculation of number of entries per PTE in page tables

2020-09-17 Thread Michael Ellerman
On Mon, 31 Aug 2020 08:30:43 + (UTC), Christophe Leroy wrote:
> On 8xx, the number of entries occupied by a PTE in the page tables
> depends on the size of the page. At the time being, this calculation
> is done in two places: in pte_update() and in set_huge_pte_at()
> 
> Refactor this calculation into a helper called
> number_of_cells_per_pte(). For the time being, the val param is
> unused. It will be used by following patch.
> 
> [...]

Applied to powerpc/next.

[1/2] powerpc/8xx: Refactor calculation of number of entries per PTE in page 
tables
  https://git.kernel.org/powerpc/c/175a1511fed16108dcb823f0af8e72325a1f
[2/2] powerpc/8xx: Support 16k hugepages with 4k pages
  https://git.kernel.org/powerpc/c/e47168f3d1b14af5281cf50c59561d59d28201f9

cheers


[PATCH 1/2] powerpc/8xx: Refactor calculation of number of entries per PTE in page tables

2020-08-31 Thread Christophe Leroy
On 8xx, the number of entries occupied by a PTE in the page tables
depends on the size of the page. At the time being, this calculation
is done in two places: in pte_update() and in set_huge_pte_at()

Refactor this calculation into a helper called
number_of_cells_per_pte(). For the time being, the val param is
unused. It will be used by following patch.

Instead of opencoding is_hugepd(), use hugepd_ok() with a forward
declaration.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/nohash/32/pgtable.h | 18 --
 arch/powerpc/mm/pgtable.c|  6 --
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index b9e134d0f03a..80bbc21b87f0 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -227,6 +227,17 @@ static inline void pmd_clear(pmd_t *pmdp)
  */
 #ifdef CONFIG_PPC_8xx
 static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr);
+static int hugepd_ok(hugepd_t hpd);
+
+static int number_of_cells_per_pte(pmd_t *pmd, pte_basic_t val, int huge)
+{
+   if (!huge)
+   return PAGE_SIZE / SZ_4K;
+   else if (hugepd_ok(*((hugepd_t *)pmd)))
+   return 1;
+   else
+   return SZ_512K / SZ_4K;
+}
 
 static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, 
pte_t *p,
 unsigned long clr, unsigned long set, int 
huge)
@@ -237,12 +248,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, 
unsigned long addr, p
int num, i;
pmd_t *pmd = pmd_off(mm, addr);
 
-   if (!huge)
-   num = PAGE_SIZE / SZ_4K;
-   else if ((pmd_val(*pmd) & _PMD_PAGE_MASK) != _PMD_PAGE_8M)
-   num = SZ_512K / SZ_4K;
-   else
-   num = 1;
+   num = number_of_cells_per_pte(pmd, new, huge);
 
for (i = 0; i < num; i++, entry++, new += SZ_4K)
*entry = new;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 9c0547d77af3..2dcad640b869 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -266,8 +266,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long 
addr, pte_t *ptep, pte_
pmd_t *pmd = pmd_off(mm, addr);
pte_basic_t val;
pte_basic_t *entry = &ptep->pte;
-   int num = is_hugepd(*((hugepd_t *)pmd)) ? 1 : SZ_512K / SZ_4K;
-   int i;
+   int num, i;
 
/*
 * Make sure hardware valid bit is not set. We don't do
@@ -280,6 +279,9 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long 
addr, pte_t *ptep, pte_
pte = set_pte_filter(pte);
 
val = pte_val(pte);
+
+   num = number_of_cells_per_pte(pmd, val, 1);
+
for (i = 0; i < num; i++, entry++, val += SZ_4K)
*entry = val;
 }
-- 
2.25.0