Skip to content

Commit fadd03c

Browse files
kvaneeshmpe
authored andcommitted
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 0c4d268 ("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: 0c4d268 ("powerpc/book3s64/mm: Simplify the rcu callback for page table free") Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> [mpe: Add CONFIG_HUGETLB_PAGE guard to fix build break] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 758380b commit fadd03c

8 files changed

Lines changed: 52 additions & 1 deletion

File tree

arch/powerpc/include/asm/book3s/32/pgalloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ static inline void pgtable_free(void *table, unsigned index_size)
108108
}
109109

110110
#define check_pgt_cache() do { } while (0)
111+
#define get_hugepd_cache_index(x) (x)
111112

112113
#ifdef CONFIG_SMP
113114
static inline void pgtable_free_tlb(struct mmu_gather *tlb,

arch/powerpc/include/asm/book3s/64/pgtable-4k.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,27 @@ static inline int hugepd_ok(hugepd_t hpd)
4949
}
5050
#define is_hugepd(hpd) (hugepd_ok(hpd))
5151

52+
/*
53+
* 16M and 16G huge page directory tables are allocated from slab cache
54+
*
55+
*/
56+
#define H_16M_CACHE_INDEX (PAGE_SHIFT + H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE - 24)
57+
#define H_16G_CACHE_INDEX \
58+
(PAGE_SHIFT + H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE + H_PUD_INDEX_SIZE - 34)
59+
60+
static inline int get_hugepd_cache_index(int index)
61+
{
62+
switch (index) {
63+
case H_16M_CACHE_INDEX:
64+
return HTLB_16M_INDEX;
65+
case H_16G_CACHE_INDEX:
66+
return HTLB_16G_INDEX;
67+
default:
68+
BUG();
69+
}
70+
/* should not reach */
71+
}
72+
5273
#else /* !CONFIG_HUGETLB_PAGE */
5374
static inline int pmd_huge(pmd_t pmd) { return 0; }
5475
static inline int pud_huge(pud_t pud) { return 0; }

arch/powerpc/include/asm/book3s/64/pgtable-64k.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,17 @@ static inline int hugepd_ok(hugepd_t hpd)
4545
{
4646
return 0;
4747
}
48+
4849
#define is_hugepd(pdep) 0
4950

51+
/*
52+
* This should never get called
53+
*/
54+
static inline int get_hugepd_cache_index(int index)
55+
{
56+
BUG();
57+
}
58+
5059
#else /* !CONFIG_HUGETLB_PAGE */
5160
static inline int pmd_huge(pmd_t pmd) { return 0; }
5261
static inline int pud_huge(pud_t pud) { return 0; }

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ enum pgtable_index {
287287
PMD_INDEX,
288288
PUD_INDEX,
289289
PGD_INDEX,
290+
/*
291+
* Below are used with 4k page size and hugetlb
292+
*/
293+
HTLB_16M_INDEX,
294+
HTLB_16G_INDEX,
290295
};
291296

292297
extern unsigned long __vmalloc_start;

arch/powerpc/include/asm/nohash/32/pgalloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static inline void pgtable_free(void *table, unsigned index_size)
109109
}
110110

111111
#define check_pgt_cache() do { } while (0)
112+
#define get_hugepd_cache_index(x) (x)
112113

113114
#ifdef CONFIG_SMP
114115
static inline void pgtable_free_tlb(struct mmu_gather *tlb,

arch/powerpc/include/asm/nohash/64/pgalloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static inline void pgtable_free(void *table, int shift)
141141
}
142142
}
143143

144+
#define get_hugepd_cache_index(x) (x)
144145
#ifdef CONFIG_SMP
145146
static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
146147
{

arch/powerpc/mm/hugetlbpage.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif
337337
if (shift >= pdshift)
338338
hugepd_free(tlb, hugepte);
339339
else
340-
pgtable_free_tlb(tlb, hugepte, pdshift - shift);
340+
pgtable_free_tlb(tlb, hugepte,
341+
get_hugepd_cache_index(pdshift - shift));
341342
}
342343

343344
static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,

arch/powerpc/mm/pgtable-book3s64.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,18 @@ static inline void pgtable_free(void *table, int index)
409409
case PUD_INDEX:
410410
kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), table);
411411
break;
412+
#if defined(CONFIG_PPC_4K_PAGES) && defined(CONFIG_HUGETLB_PAGE)
413+
/* 16M hugepd directory at pud level */
414+
case HTLB_16M_INDEX:
415+
BUILD_BUG_ON(H_16M_CACHE_INDEX <= 0);
416+
kmem_cache_free(PGT_CACHE(H_16M_CACHE_INDEX), table);
417+
break;
418+
/* 16G hugepd directory at the pgd level */
419+
case HTLB_16G_INDEX:
420+
BUILD_BUG_ON(H_16G_CACHE_INDEX <= 0);
421+
kmem_cache_free(PGT_CACHE(H_16G_CACHE_INDEX), table);
422+
break;
423+
#endif
412424
/* We don't free pgd table via RCU callback */
413425
default:
414426
BUG();

0 commit comments

Comments
 (0)