aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/Kconfig4
-rw-r--r--arch/sparc/include/asm/pgalloc_64.h32
-rw-r--r--arch/sparc/mm/tsb.c11
3 files changed, 26 insertions, 21 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 253986bd6bb6..af64348775e2 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -81,10 +81,6 @@ config IOMMU_HELPER
81 bool 81 bool
82 default y if SPARC64 82 default y if SPARC64
83 83
84config QUICKLIST
85 bool
86 default y if SPARC64
87
88config STACKTRACE_SUPPORT 84config STACKTRACE_SUPPORT
89 bool 85 bool
90 default y if SPARC64 86 default y if SPARC64
diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h
index 4e5e0878144f..cb4867de06a2 100644
--- a/arch/sparc/include/asm/pgalloc_64.h
+++ b/arch/sparc/include/asm/pgalloc_64.h
@@ -5,7 +5,6 @@
5#include <linux/sched.h> 5#include <linux/sched.h>
6#include <linux/mm.h> 6#include <linux/mm.h>
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include <linux/quicklist.h>
9 8
10#include <asm/spitfire.h> 9#include <asm/spitfire.h>
11#include <asm/cpudata.h> 10#include <asm/cpudata.h>
@@ -14,69 +13,68 @@
14 13
15/* Page table allocation/freeing. */ 14/* Page table allocation/freeing. */
16 15
16extern struct kmem_cache *pgtable_cache;
17
17static inline pgd_t *pgd_alloc(struct mm_struct *mm) 18static inline pgd_t *pgd_alloc(struct mm_struct *mm)
18{ 19{
19 return quicklist_alloc(0, GFP_KERNEL, NULL); 20 return kmem_cache_alloc(pgtable_cache, GFP_KERNEL);
20} 21}
21 22
22static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 23static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
23{ 24{
24 quicklist_free(0, NULL, pgd); 25 kmem_cache_free(pgtable_cache, pgd);
25} 26}
26 27
27#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) 28#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD)
28 29
29static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) 30static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
30{ 31{
31 return quicklist_alloc(0, GFP_KERNEL, NULL); 32 return kmem_cache_alloc(pgtable_cache,
33 GFP_KERNEL|__GFP_REPEAT);
32} 34}
33 35
34static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) 36static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
35{ 37{
36 quicklist_free(0, NULL, pmd); 38 kmem_cache_free(pgtable_cache, pmd);
37} 39}
38 40
39static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 41static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
40 unsigned long address) 42 unsigned long address)
41{ 43{
42 return quicklist_alloc(0, GFP_KERNEL, NULL); 44 return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
43} 45}
44 46
45static inline pgtable_t pte_alloc_one(struct mm_struct *mm, 47static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
46 unsigned long address) 48 unsigned long address)
47{ 49{
48 struct page *page; 50 struct page *page;
49 void *pg; 51 pte_t *pte;
50 52
51 pg = quicklist_alloc(0, GFP_KERNEL, NULL); 53 pte = pte_alloc_one_kernel(mm, address);
52 if (!pg) 54 if (!pte)
53 return NULL; 55 return NULL;
54 page = virt_to_page(pg); 56 page = virt_to_page(pte);
55 pgtable_page_ctor(page); 57 pgtable_page_ctor(page);
56 return page; 58 return page;
57} 59}
58 60
59static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 61static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
60{ 62{
61 quicklist_free(0, NULL, pte); 63 free_page((unsigned long)pte);
62} 64}
63 65
64static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) 66static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
65{ 67{
66 pgtable_page_dtor(ptepage); 68 pgtable_page_dtor(ptepage);
67 quicklist_free_page(0, NULL, ptepage); 69 __free_page(ptepage);
68} 70}
69 71
70
71#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) 72#define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE)
72#define pmd_populate(MM,PMD,PTE_PAGE) \ 73#define pmd_populate(MM,PMD,PTE_PAGE) \
73 pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) 74 pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
74#define pmd_pgtable(pmd) pmd_page(pmd) 75#define pmd_pgtable(pmd) pmd_page(pmd)
75 76
76static inline void check_pgt_cache(void) 77#define check_pgt_cache() do { } while (0)
77{
78 quicklist_trim(0, NULL, 25, 16);
79}
80 78
81#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) 79#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
82#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd) 80#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index a5f51b22fcbe..536412d8f416 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -236,6 +236,8 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign
236 } 236 }
237} 237}
238 238
239struct kmem_cache *pgtable_cache __read_mostly;
240
239static struct kmem_cache *tsb_caches[8] __read_mostly; 241static struct kmem_cache *tsb_caches[8] __read_mostly;
240 242
241static const char *tsb_cache_names[8] = { 243static const char *tsb_cache_names[8] = {
@@ -253,6 +255,15 @@ void __init pgtable_cache_init(void)
253{ 255{
254 unsigned long i; 256 unsigned long i;
255 257
258 pgtable_cache = kmem_cache_create("pgtable_cache",
259 PAGE_SIZE, PAGE_SIZE,
260 0,
261 _clear_page);
262 if (!pgtable_cache) {
263 prom_printf("pgtable_cache_init(): Could not create!\n");
264 prom_halt();
265 }
266
256 for (i = 0; i < 8; i++) { 267 for (i = 0; i < 8; i++) {
257 unsigned long size = 8192 << i; 268 unsigned long size = 8192 << i;
258 const char *name = tsb_cache_names[i]; 269 const char *name = tsb_cache_names[i];