Skip to contentSkip to conversation

powerpc/mm/hash/4k: Free hugetlb page table caches correctly.

PATCH Applied Aneesh Kumar K.V 3 participants 4 messages Jun 14, 2018 – Jun 23, 2018 PowerPC

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 powerpc/mm/hash/4k: Free hugetlb page table caches correctly.

With 4k page size for hugetlb we allocate hugepage directories from its on slab cache. With patch 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free") we missed to free these allocated hugepd tables.

Update pgtable_free to handle hugetlb hugepd directory table.

Fixes 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free")
---
 arch/powerpc/include/asm/book3s/32/pgalloc.h  |  1 +
 .../include/asm/book3s/64/pgtable-4k.h        | 21 +++++++++++++++++++
 .../include/asm/book3s/64/pgtable-64k.h       |  9 ++++++++
 arch/powerpc/include/asm/book3s/64/pgtable.h  |  5 +++++
 arch/powerpc/include/asm/nohash/32/pgalloc.h  |  1 +
 arch/powerpc/include/asm/nohash/64/pgalloc.h  |  1 +
 arch/powerpc/mm/hugetlbpage.c                 |  3 ++-
 arch/powerpc/mm/pgtable-book3s64.c            | 12 +++++++++++
 8 files changed, 52 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/book3s/32/pgalloc.h +1 -0
index 6a6673907e45..e4633803fe43 100644
@@ -108,6 +108,7 @@ static inline void pgtable_free(void *table, unsigned index_size)
 }
 
 #define check_pgt_cache()	do { } while (0)
+#define get_hugepd_cache_index(x)  (x)
 
 #ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb,
arch/powerpc/include/asm/book3s/64/pgtable-4k.h +21 -0
index af5f2baac80f..a069dfcac9a9 100644
@@ -49,6 +49,27 @@ static inline int hugepd_ok(hugepd_t hpd)
 }
 #define is_hugepd(hpd)		(hugepd_ok(hpd))
 
+/*
+ * 16M and 16G huge page directory tables are allocated from slab cache
+ *
+ */
+#define H_16M_CACHE_INDEX (PAGE_SHIFT + H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE - 24)
+#define H_16G_CACHE_INDEX                                                      \
+	(PAGE_SHIFT + H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE + H_PUD_INDEX_SIZE - 34)
+
+static inline int get_hugepd_cache_index(int index)
+{
+	switch (index) {
+	case H_16M_CACHE_INDEX:
+		return HTLB_16M_INDEX;
+	case H_16G_CACHE_INDEX:
+		return HTLB_16G_INDEX;
+	default:
+		BUG();
+	}
+	/* should not reach */
+}
+
 #else /* !CONFIG_HUGETLB_PAGE */
 static inline int pmd_huge(pmd_t pmd) { return 0; }
 static inline int pud_huge(pud_t pud) { return 0; }
arch/powerpc/include/asm/book3s/64/pgtable-64k.h +9 -0
index fb4b3ba52339..d7ee249d6890 100644
@@ -45,8 +45,17 @@ static inline int hugepd_ok(hugepd_t hpd)
 {
 	return 0;
 }
+
 #define is_hugepd(pdep)			0
 
+/*
+ * This should never get called
+ */
+static inline int get_hugepd_cache_index(int index)
+{
+	BUG();
+}
+
 #else /* !CONFIG_HUGETLB_PAGE */
 static inline int pmd_huge(pmd_t pmd) { return 0; }
 static inline int pud_huge(pud_t pud) { return 0; }
arch/powerpc/include/asm/book3s/64/pgtable.h +5 -0
index 42fe7c2ff2df..1022f622397f 100644
@@ -287,6 +287,11 @@ enum pgtable_index {
 	PMD_INDEX,
 	PUD_INDEX,
 	PGD_INDEX,
+	/*
+	 * Below are used with 4k page size and hugetlb
+	 */
+	HTLB_16M_INDEX,
+	HTLB_16G_INDEX,
 };
 
 extern unsigned long __vmalloc_start;
arch/powerpc/include/asm/nohash/32/pgalloc.h +1 -0
index 1707781d2f20..9de40eb614da 100644
@@ -109,6 +109,7 @@ static inline void pgtable_free(void *table, unsigned index_size)
 }
 
 #define check_pgt_cache()	do { } while (0)
+#define get_hugepd_cache_index(x)	(x)
 
 #ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb,
arch/powerpc/include/asm/nohash/64/pgalloc.h +1 -0
index 0e693f322cb2..e2d62d033708 100644
@@ -141,6 +141,7 @@ static inline void pgtable_free(void *table, int shift)
 	}
 }
 
+#define get_hugepd_cache_index(x)	(x)
 #ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
 {
arch/powerpc/mm/hugetlbpage.c +2 -1
index 7c5f479c5c00..8a9a49c13865 100644
@@ -337,7 +337,8 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif
 	if (shift >= pdshift)
 		hugepd_free(tlb, hugepte);
 	else
-		pgtable_free_tlb(tlb, hugepte, pdshift - shift);
+		pgtable_free_tlb(tlb, hugepte,
+				 get_hugepd_cache_index(pdshift - shift));
 }
 
 static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
arch/powerpc/mm/pgtable-book3s64.c +12 -0
index c1f4ca45c93a..468c3d83a2aa 100644
@@ -409,6 +409,18 @@ static inline void pgtable_free(void *table, int index)
 	case PUD_INDEX:
 		kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), table);
 		break;
+#ifdef CONFIG_PPC_4K_PAGES
+		/* 16M hugepd directory at pud level */
+	case HTLB_16M_INDEX:
+		BUILD_BUG_ON(H_16M_CACHE_INDEX <= 0);
+		kmem_cache_free(PGT_CACHE(H_16M_CACHE_INDEX), table);
+		break;
+		/* 16G hugepd directory at the pgd level */
+	case HTLB_16G_INDEX:
+		BUILD_BUG_ON(H_16G_CACHE_INDEX <= 0);
+		kmem_cache_free(PGT_CACHE(H_16G_CACHE_INDEX), table);
+		break;
+#endif
 		/* We don't free pgd table via RCU callback */
 	default:
 		BUG();
Signature · 1 line
2.17.1
#1 lore raw
Quoted 1 line · Aneesh Kumar K.V

With 4k page size for hugetlb we allocate hugepage directories from its o=

n slab

Quoted 1 line

cache. With patch 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callb=

ack for page table free")

Quoted 5 lines

we missed to free these allocated hugepd tables.

Update pgtable_free to handle hugetlb hugepd directory table.

Fixes 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for pa=

ge table free")

Quoted 10 lines
---
 arch/powerpc/include/asm/book3s/32/pgalloc.h  |  1 +
 .../include/asm/book3s/64/pgtable-4k.h        | 21 +++++++++++++++++++
 .../include/asm/book3s/64/pgtable-64k.h       |  9 ++++++++
 arch/powerpc/include/asm/book3s/64/pgtable.h  |  5 +++++
 arch/powerpc/include/asm/nohash/32/pgalloc.h  |  1 +
 arch/powerpc/include/asm/nohash/64/pgalloc.h  |  1 +
 arch/powerpc/mm/hugetlbpage.c                 |  3 ++-
 arch/powerpc/mm/pgtable-book3s64.c            | 12 +++++++++++

Fails with 4K=3Dy HUGETLBFS=3Dn:

arch/powerpc/mm/pgtable-book3s64.c:415:16: error: =E2=80=98H_16M_CACHE_IN=
DEX=E2=80=99 undeclared (first use in this function); did you mean =E2=80= =98H_PUD_CACHE_INDEX=E2=80=99?

...

arch/powerpc/mm/pgtable=

Quoted 1 line
arch/powerpc/mm/pgtable= renamed from arch/powerpc/mm/pgtable-book3s64.c +0 -0

-book3s64.c

arch/powerpc/mm/pgtable-book3s64.c static inline void pgtable_free(void *table, int ind=

Quoted 4 lines

index c1f4ca45c93a..468c3d83a2aa 100644

arch/powerpc/mm/pgtable-book3s64.c +0 -0
@@ -409,6 +409,18 @@ static inline void pgtable_free(void *table, int ind=

ex)

Quoted 5 lines
arch/powerpc/mm/pgtable-book3s64.c +2 -0
 	case PUD_INDEX:
 		kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), table);
 		break;
+#ifdef CONFIG_PPC_4K_PAGES
+		/* 16M hugepd directory at pud level */

arch/powerpc/mm/pgtable-book3s64.c static inline void pgtable_free(void *table, int ind= · line 423

Quoted 10 lines
arch/powerpc/mm/pgtable-book3s64.c +10 -0
+	case HTLB_16M_INDEX:
+		BUILD_BUG_ON(H_16M_CACHE_INDEX <=3D 0);
+		kmem_cache_free(PGT_CACHE(H_16M_CACHE_INDEX), table);
+		break;
+		/* 16G hugepd directory at the pgd level */
+	case HTLB_16G_INDEX:
+		BUILD_BUG_ON(H_16G_CACHE_INDEX <=3D 0);
+		kmem_cache_free(PGT_CACHE(H_16G_CACHE_INDEX), table);
+		break;
+#endif

Because this isn't protected by CONFIG_HUGETLBFS.

I assume this is correct?

arch/powerpc/mm/pgtable-b= renamed from arch/powerpc/mm/pgtable-book3s64.c +0 -0

ook3s64.c
index 468c3d83a2aa..9b7007fd075e 100644

arch/powerpc/mm/pgtable-book3s64.c +1 -1
@@ -409,7 +409,7 @@ static inline void pgtable_free(void *table, int index)
 	case PUD_INDEX:
 		kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), table);
 		break;
-#ifdef CONFIG_PPC_4K_PAGES
+#if defined(CONFIG_PPC_4K_PAGES) && defined (CONFIG_HUGETLBFS)
 		/* 16M hugepd directory at pud level */
 	case HTLB_16M_INDEX:
 		BUILD_BUG_ON(H_16M_CACHE_INDEX <=3D 0);

cheers

#2 lore raw
Quoted 66 lines · Michael Ellerman
Quoted 8 lines · Aneesh Kumar K.V

With 4k page size for hugetlb we allocate hugepage directories from its on slab cache. With patch 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free") we missed to free these allocated hugepd tables.

Update pgtable_free to handle hugetlb hugepd directory table.

Fixes 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free")
Quoted 9 lines
---
  arch/powerpc/include/asm/book3s/32/pgalloc.h  |  1 +
  .../include/asm/book3s/64/pgtable-4k.h        | 21 +++++++++++++++++++
  .../include/asm/book3s/64/pgtable-64k.h       |  9 ++++++++
  arch/powerpc/include/asm/book3s/64/pgtable.h  |  5 +++++
  arch/powerpc/include/asm/nohash/32/pgalloc.h  |  1 +
  arch/powerpc/include/asm/nohash/64/pgalloc.h  |  1 +
  arch/powerpc/mm/hugetlbpage.c                 |  3 ++-
  arch/powerpc/mm/pgtable-book3s64.c            | 12 +++++++++++

Fails with 4K=y HUGETLBFS=n:

arch/powerpc/mm/pgtable-book3s64.c:415:16: error: ‘H_16M_CACHE_INDEX’ undeclared (first use in this function); did you mean ‘H_PUD_CACHE_INDEX’?

...

Quoted 10 lines
arch/powerpc/mm/pgtable-book3s64.c +2 -0
index c1f4ca45c93a..468c3d83a2aa 100644
@@ -409,6 +409,18 @@ static inline void pgtable_free(void *table, int index)
  	case PUD_INDEX:
  		kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), table);
  		break;
+#ifdef CONFIG_PPC_4K_PAGES
+		/* 16M hugepd directory at pud level */

arch/powerpc/mm/pgtable-book3s64.c static inline void pgtable_free(void *table, int index) · line 423

Quoted 10 lines
arch/powerpc/mm/pgtable-book3s64.c +10 -0
+	case HTLB_16M_INDEX:
+		BUILD_BUG_ON(H_16M_CACHE_INDEX <= 0);
+		kmem_cache_free(PGT_CACHE(H_16M_CACHE_INDEX), table);
+		break;
+		/* 16G hugepd directory at the pgd level */
+	case HTLB_16G_INDEX:
+		BUILD_BUG_ON(H_16G_CACHE_INDEX <= 0);
+		kmem_cache_free(PGT_CACHE(H_16G_CACHE_INDEX), table);
+		break;
+#endif

Because this isn't protected by CONFIG_HUGETLBFS.

I assume this is correct?

arch/powerpc/mm/pgtable-book3s64.c +1 -1
index 468c3d83a2aa..9b7007fd075e 100644
@@ -409,7 +409,7 @@ static inline void pgtable_free(void *table, int index)
  	case PUD_INDEX:
  		kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), table);
  		break;
-#ifdef CONFIG_PPC_4K_PAGES
+#if defined(CONFIG_PPC_4K_PAGES) && defined (CONFIG_HUGETLBFS)
  		/* 16M hugepd directory at pud level */
  	case HTLB_16M_INDEX:
  		BUILD_BUG_ON(H_16M_CACHE_INDEX <= 0);
Quoted 2 lines

cheers

Sorry missed that. Can we use #ifdef CONFIG_HUGETLB_PAGE ? That is what we use to protect that in pgtable-4k.h

-aneesh

-aneesh

#3 lore raw
In reply to Aneesh Kumar K.V
Quoted 8 lines · Aneesh Kumar K.V

With 4k page size for hugetlb we allocate hugepage directories from its on slab cache. With patch 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free") we missed to free these allocated hugepd tables.

Update pgtable_free to handle hugetlb hugepd directory table.

Fixes 0c4d26802 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free")

Applied to powerpc fixes, thanks.

https://git.kernel.org/powerpc/c/fadd03c615922d8521a2e76d4ba233

cheers