aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc32.h4
-rw-r--r--arch/powerpc/mm/pgtable_32.c16
2 files changed, 18 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index 9cde3c1522e3..26ce0ab0a9e4 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -347,10 +347,14 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
347#define pte_to_pgoff(pte) (pte_val(pte) >> 3) 347#define pte_to_pgoff(pte) (pte_val(pte) >> 3)
348#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE }) 348#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE })
349 349
350#ifndef CONFIG_PPC_4K_PAGES
351void pgtable_cache_init(void);
352#else
350/* 353/*
351 * No page table caches to initialise 354 * No page table caches to initialise
352 */ 355 */
353#define pgtable_cache_init() do { } while (0) 356#define pgtable_cache_init() do { } while (0)
357#endif
354 358
355extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, 359extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
356 pmd_t **pmdp); 360 pmd_t **pmdp);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 833139620431..03b1a3b0fbd5 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -72,13 +72,25 @@ extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa);
72 72
73#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) 73#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)
74 74
75#ifndef CONFIG_PPC_4K_PAGES
76static struct kmem_cache *pgtable_cache;
77
78void pgtable_cache_init(void)
79{
80 pgtable_cache = kmem_cache_create("PGDIR cache", 1 << PGDIR_ORDER,
81 1 << PGDIR_ORDER, 0, NULL);
82 if (pgtable_cache == NULL)
83 panic("Couldn't allocate pgtable caches");
84}
85#endif
86
75pgd_t *pgd_alloc(struct mm_struct *mm) 87pgd_t *pgd_alloc(struct mm_struct *mm)
76{ 88{
77 pgd_t *ret; 89 pgd_t *ret;
78 90
79 /* pgdir take page or two with 4K pages and a page fraction otherwise */ 91 /* pgdir take page or two with 4K pages and a page fraction otherwise */
80#ifndef CONFIG_PPC_4K_PAGES 92#ifndef CONFIG_PPC_4K_PAGES
81 ret = kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); 93 ret = kmem_cache_alloc(pgtable_cache, GFP_KERNEL | __GFP_ZERO);
82#else 94#else
83 ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 95 ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
84 PGDIR_ORDER - PAGE_SHIFT); 96 PGDIR_ORDER - PAGE_SHIFT);
@@ -89,7 +101,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
89void pgd_free(struct mm_struct *mm, pgd_t *pgd) 101void pgd_free(struct mm_struct *mm, pgd_t *pgd)
90{ 102{
91#ifndef CONFIG_PPC_4K_PAGES 103#ifndef CONFIG_PPC_4K_PAGES
92 kfree((void *)pgd); 104 kmem_cache_free(pgtable_cache, (void *)pgd);
93#else 105#else
94 free_pages((unsigned long)pgd, PGDIR_ORDER - PAGE_SHIFT); 106 free_pages((unsigned long)pgd, PGDIR_ORDER - PAGE_SHIFT);
95#endif 107#endif