diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2007-05-13 20:55:35 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2007-05-13 20:55:35 -0400 |
| commit | 6c645ac72582bacb85b90a1cf88e81a13045aba4 (patch) | |
| tree | a6101de4bd5426ebfb06b097749251ff6f9e98b2 | |
| parent | e827f20f1d34e91fbbb0df4674ddd8c3aad517da (diff) | |
sh64: generic quicklist support.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
| -rw-r--r-- | arch/sh64/Kconfig | 3 | ||||
| -rw-r--r-- | arch/sh64/mm/init.c | 2 | ||||
| -rw-r--r-- | include/asm-sh64/pgalloc.h | 100 | ||||
| -rw-r--r-- | mm/Kconfig | 2 |
4 files changed, 28 insertions, 79 deletions
diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig index e14b533558c8..ff654204b7d4 100644 --- a/arch/sh64/Kconfig +++ b/arch/sh64/Kconfig | |||
| @@ -17,6 +17,9 @@ config MMU | |||
| 17 | bool | 17 | bool |
| 18 | default y | 18 | default y |
| 19 | 19 | ||
| 20 | config QUICKLIST | ||
| 21 | def_bool y | ||
| 22 | |||
| 20 | config RWSEM_GENERIC_SPINLOCK | 23 | config RWSEM_GENERIC_SPINLOCK |
| 21 | bool | 24 | bool |
| 22 | default y | 25 | default y |
diff --git a/arch/sh64/mm/init.c b/arch/sh64/mm/init.c index 5dc08787259c..559717f30d1f 100644 --- a/arch/sh64/mm/init.c +++ b/arch/sh64/mm/init.c | |||
| @@ -84,7 +84,7 @@ void show_mem(void) | |||
| 84 | printk("%d reserved pages\n",reserved); | 84 | printk("%d reserved pages\n",reserved); |
| 85 | printk("%d pages shared\n",shared); | 85 | printk("%d pages shared\n",shared); |
| 86 | printk("%d pages swap cached\n",cached); | 86 | printk("%d pages swap cached\n",cached); |
| 87 | printk("%ld pages in page table cache\n",pgtable_cache_size); | 87 | printk("%ld pages in page table cache\n", quicklist_total_size()); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | /* | 90 | /* |
diff --git a/include/asm-sh64/pgalloc.h b/include/asm-sh64/pgalloc.h index cb803e56cb64..6eccab770a6d 100644 --- a/include/asm-sh64/pgalloc.h +++ b/include/asm-sh64/pgalloc.h | |||
| @@ -14,13 +14,9 @@ | |||
| 14 | * | 14 | * |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/threads.h> | ||
| 18 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 19 | 18 | #include <linux/quicklist.h> | |
| 20 | #define pgd_quicklist (current_cpu_data.pgd_quick) | 19 | #include <asm/page.h> |
| 21 | #define pmd_quicklist (current_cpu_data.pmd_quick) | ||
| 22 | #define pte_quicklist (current_cpu_data.pte_quick) | ||
| 23 | #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) | ||
| 24 | 20 | ||
| 25 | static inline void pgd_init(unsigned long page) | 21 | static inline void pgd_init(unsigned long page) |
| 26 | { | 22 | { |
| @@ -45,84 +41,37 @@ static inline pgd_t *get_pgd_slow(void) | |||
| 45 | return ret; | 41 | return ret; |
| 46 | } | 42 | } |
| 47 | 43 | ||
| 48 | static inline pgd_t *get_pgd_fast(void) | 44 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
| 49 | { | ||
| 50 | unsigned long *ret; | ||
| 51 | |||
| 52 | if ((ret = pgd_quicklist) != NULL) { | ||
| 53 | pgd_quicklist = (unsigned long *)(*ret); | ||
| 54 | ret[0] = 0; | ||
| 55 | pgtable_cache_size--; | ||
| 56 | } else | ||
| 57 | ret = (unsigned long *)get_pgd_slow(); | ||
| 58 | |||
| 59 | if (ret) { | ||
| 60 | memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); | ||
| 61 | } | ||
| 62 | return (pgd_t *)ret; | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline void free_pgd_fast(pgd_t *pgd) | ||
| 66 | { | ||
| 67 | *(unsigned long *)pgd = (unsigned long) pgd_quicklist; | ||
| 68 | pgd_quicklist = (unsigned long *) pgd; | ||
| 69 | pgtable_cache_size++; | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline void free_pgd_slow(pgd_t *pgd) | ||
| 73 | { | 45 | { |
| 74 | kfree((void *)pgd); | 46 | return quicklist_alloc(0, GFP_KERNEL, NULL); |
| 75 | } | 47 | } |
| 76 | 48 | ||
| 77 | extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); | 49 | static inline void pgd_free(pgd_t *pgd) |
| 78 | extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted); | ||
| 79 | |||
| 80 | static inline pte_t *get_pte_fast(void) | ||
| 81 | { | 50 | { |
| 82 | unsigned long *ret; | 51 | quicklist_free(0, NULL, pgd); |
| 83 | |||
| 84 | if((ret = (unsigned long *)pte_quicklist) != NULL) { | ||
| 85 | pte_quicklist = (unsigned long *)(*ret); | ||
| 86 | ret[0] = ret[1]; | ||
| 87 | pgtable_cache_size--; | ||
| 88 | } | ||
| 89 | return (pte_t *)ret; | ||
| 90 | } | 52 | } |
| 91 | 53 | ||
| 92 | static inline void free_pte_fast(pte_t *pte) | 54 | static inline struct page *pte_alloc_one(struct mm_struct *mm, |
| 55 | unsigned long address) | ||
| 93 | { | 56 | { |
| 94 | *(unsigned long *)pte = (unsigned long) pte_quicklist; | 57 | void *pg = quicklist_alloc(0, GFP_KERNEL, NULL); |
| 95 | pte_quicklist = (unsigned long *) pte; | 58 | return pg ? virt_to_page(pg) : NULL; |
| 96 | pgtable_cache_size++; | ||
| 97 | } | 59 | } |
| 98 | 60 | ||
| 99 | static inline void pte_free_kernel(pte_t *pte) | 61 | static inline void pte_free_kernel(pte_t *pte) |
| 100 | { | 62 | { |
| 101 | free_page((unsigned long)pte); | 63 | quicklist_free(0, NULL, pte); |
| 102 | } | 64 | } |
| 103 | 65 | ||
| 104 | static inline void pte_free(struct page *pte) | 66 | static inline void pte_free(struct page *pte) |
| 105 | { | 67 | { |
| 106 | __free_page(pte); | 68 | quicklist_free_page(0, NULL, pte); |
| 107 | } | 69 | } |
| 108 | 70 | ||
| 109 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 71 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
| 110 | unsigned long address) | 72 | unsigned long address) |
| 111 | { | 73 | { |
| 112 | pte_t *pte; | 74 | return quicklist_alloc(0, GFP_KERNEL, NULL); |
| 113 | |||
| 114 | pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT|__GFP_ZERO); | ||
| 115 | |||
| 116 | return pte; | ||
| 117 | } | ||
| 118 | |||
| 119 | static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) | ||
| 120 | { | ||
| 121 | struct page *pte; | ||
| 122 | |||
| 123 | pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); | ||
| 124 | |||
| 125 | return pte; | ||
| 126 | } | 75 | } |
| 127 | 76 | ||
| 128 | #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) | 77 | #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) |
| @@ -142,31 +91,23 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long add | |||
| 142 | 91 | ||
| 143 | #elif defined(CONFIG_SH64_PGTABLE_3_LEVEL) | 92 | #elif defined(CONFIG_SH64_PGTABLE_3_LEVEL) |
| 144 | 93 | ||
| 145 | static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | 94 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) |
| 146 | { | 95 | { |
| 147 | pmd_t *pmd; | 96 | return quicklist_alloc(0, GFP_KERNEL, NULL); |
| 148 | pmd = (pmd_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | ||
| 149 | return pmd; | ||
| 150 | } | 97 | } |
| 151 | 98 | ||
| 152 | static __inline__ void pmd_free(pmd_t *pmd) | 99 | static inline void pmd_free(pmd_t *pmd) |
| 153 | { | 100 | { |
| 154 | free_page((unsigned long) pmd); | 101 | quicklist_free(0, NULL, pmd); |
| 155 | } | 102 | } |
| 156 | 103 | ||
| 157 | #define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) | 104 | #define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) |
| 158 | #define __pmd_free_tlb(tlb,pmd) pmd_free(pmd) | 105 | #define __pmd_free_tlb(tlb,pmd) pmd_free(pmd) |
| 159 | 106 | ||
| 160 | #else | 107 | #else |
| 161 | #error "No defined page table size" | 108 | #error "No defined page table size" |
| 162 | #endif | 109 | #endif |
| 163 | 110 | ||
| 164 | #define check_pgt_cache() do { } while (0) | ||
| 165 | #define pgd_free(pgd) free_pgd_slow(pgd) | ||
| 166 | #define pgd_alloc(mm) get_pgd_fast() | ||
| 167 | |||
| 168 | extern int do_check_pgt_cache(int, int); | ||
| 169 | |||
| 170 | #define pmd_populate_kernel(mm, pmd, pte) \ | 111 | #define pmd_populate_kernel(mm, pmd, pte) \ |
| 171 | set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) (pte))) | 112 | set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) (pte))) |
| 172 | 113 | ||
| @@ -176,4 +117,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | |||
| 176 | set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) page_address (pte))); | 117 | set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) page_address (pte))); |
| 177 | } | 118 | } |
| 178 | 119 | ||
| 120 | static inline void check_pgt_cache(void) | ||
| 121 | { | ||
| 122 | quicklist_trim(0, NULL, 25, 16); | ||
| 123 | } | ||
| 124 | |||
| 179 | #endif /* __ASM_SH64_PGALLOC_H */ | 125 | #endif /* __ASM_SH64_PGALLOC_H */ |
diff --git a/mm/Kconfig b/mm/Kconfig index a17da8bafe62..8ac412b45f18 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
| @@ -166,5 +166,5 @@ config ZONE_DMA_FLAG | |||
| 166 | config NR_QUICK | 166 | config NR_QUICK |
| 167 | int | 167 | int |
| 168 | depends on QUICKLIST | 168 | depends on QUICKLIST |
| 169 | default "2" if SUPERH | 169 | default "2" if (SUPERH && !SUPERH64) |
| 170 | default "1" | 170 | default "1" |
