aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2013-11-14 17:31:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 19:32:19 -0500
commitf820e2805c7acb157a78438d07e47f4fc57fe679 (patch)
tree53d638a93450e21eaefcce74495a512e56623fc6
parent01058e70767de7b846588ef651c4d66e862f6823 (diff)
xtensa: use buddy allocator for PTE table
At the moment xtensa uses slab allocator for PTE table. It doesn't work with enabled split page table lock: slab uses page->slab_cache and page->first_page for its pages. These fields share stroage with page->ptl. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Chris Zankel <chris@zankel.net> Acked-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/xtensa/include/asm/pgalloc.h20
-rw-r--r--arch/xtensa/include/asm/pgtable.h3
-rw-r--r--arch/xtensa/mm/mmu.c20
3 files changed, 13 insertions, 30 deletions
diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h
index b8774f1e21e6..d38eb9237e64 100644
--- a/arch/xtensa/include/asm/pgalloc.h
+++ b/arch/xtensa/include/asm/pgalloc.h
@@ -38,14 +38,18 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
38 free_page((unsigned long)pgd); 38 free_page((unsigned long)pgd);
39} 39}
40 40
41/* Use a slab cache for the pte pages (see also sparc64 implementation) */
42
43extern struct kmem_cache *pgtable_cache;
44
45static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 41static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
46 unsigned long address) 42 unsigned long address)
47{ 43{
48 return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); 44 pte_t *ptep;
45 int i;
46
47 ptep = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
48 if (!ptep)
49 return NULL;
50 for (i = 0; i < 1024; i++)
51 pte_clear(NULL, 0, ptep + i);
52 return ptep;
49} 53}
50 54
51static inline pgtable_t pte_alloc_one(struct mm_struct *mm, 55static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
@@ -59,7 +63,7 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
59 return NULL; 63 return NULL;
60 page = virt_to_page(pte); 64 page = virt_to_page(pte);
61 if (!pgtable_page_ctor(page)) { 65 if (!pgtable_page_ctor(page)) {
62 kmem_cache_free(pgtable_cache, pte); 66 __free_page(page);
63 return NULL; 67 return NULL;
64 } 68 }
65 return page; 69 return page;
@@ -67,13 +71,13 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
67 71
68static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 72static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
69{ 73{
70 kmem_cache_free(pgtable_cache, pte); 74 free_page((unsigned long)pte);
71} 75}
72 76
73static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 77static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
74{ 78{
75 pgtable_page_dtor(pte); 79 pgtable_page_dtor(pte);
76 kmem_cache_free(pgtable_cache, page_address(pte)); 80 __free_page(pte);
77} 81}
78#define pmd_pgtable(pmd) pmd_page(pmd) 82#define pmd_pgtable(pmd) pmd_page(pmd)
79 83
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 0fdf5d043f82..216446295ada 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -220,12 +220,11 @@ extern unsigned long empty_zero_page[1024];
220#ifdef CONFIG_MMU 220#ifdef CONFIG_MMU
221extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)]; 221extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
222extern void paging_init(void); 222extern void paging_init(void);
223extern void pgtable_cache_init(void);
224#else 223#else
225# define swapper_pg_dir NULL 224# define swapper_pg_dir NULL
226static inline void paging_init(void) { } 225static inline void paging_init(void) { }
227static inline void pgtable_cache_init(void) { }
228#endif 226#endif
227static inline void pgtable_cache_init(void) { }
229 228
230/* 229/*
231 * The pmd contains the kernel virtual address of the pte page. 230 * The pmd contains the kernel virtual address of the pte page.
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
index a1077570e383..c43771c974be 100644
--- a/arch/xtensa/mm/mmu.c
+++ b/arch/xtensa/mm/mmu.c
@@ -50,23 +50,3 @@ void __init init_mmu(void)
50 */ 50 */
51 set_ptevaddr_register(PGTABLE_START); 51 set_ptevaddr_register(PGTABLE_START);
52} 52}
53
54struct kmem_cache *pgtable_cache __read_mostly;
55
56static void pgd_ctor(void *addr)
57{
58 pte_t *ptep = (pte_t *)addr;
59 int i;
60
61 for (i = 0; i < 1024; i++, ptep++)
62 pte_clear(NULL, 0, ptep);
63
64}
65
66void __init pgtable_cache_init(void)
67{
68 pgtable_cache = kmem_cache_create("pgd",
69 PAGE_SIZE, PAGE_SIZE,
70 SLAB_HWCACHE_ALIGN,
71 pgd_ctor);
72}