Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

FRV: Replace pgd management via slabs through quicklists

This is done in order to be able to run SLUB which expects no modifications
to its page structs.

Signed-off-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Christoph Lameter and committed by
Linus Torvalds
8defab33 34013886

+23 -15
+4 -4
arch/frv/Kconfig
··· 45 45 bool 46 46 default y 47 47 48 + config QUICKLIST 49 + bool 50 + default y 51 + 48 52 config ARCH_HAS_ILOG2_U32 49 53 bool 50 54 default y 51 55 52 56 config ARCH_HAS_ILOG2_U64 53 - bool 54 - default y 55 - 56 - config ARCH_USES_SLAB_PAGE_STRUCT 57 57 bool 58 58 default y 59 59
+4
arch/frv/kernel/process.c
··· 25 25 #include <linux/elf.h> 26 26 #include <linux/reboot.h> 27 27 #include <linux/interrupt.h> 28 + #include <linux/pagemap.h> 28 29 29 30 #include <asm/asm-offsets.h> 30 31 #include <asm/uaccess.h> 31 32 #include <asm/system.h> 32 33 #include <asm/setup.h> 33 34 #include <asm/pgtable.h> 35 + #include <asm/tlb.h> 34 36 #include <asm/gdb-stub.h> 35 37 #include <asm/mb-regs.h> 36 38 ··· 89 87 while (1) { 90 88 while (!need_resched()) { 91 89 irq_stat[cpu].idle_timestamp = jiffies; 90 + 91 + check_pgt_cache(); 92 92 93 93 if (!frv_dma_inprogress && idle) 94 94 idle();
+11 -11
arch/frv/mm/pgalloc.c
··· 13 13 #include <linux/slab.h> 14 14 #include <linux/mm.h> 15 15 #include <linux/highmem.h> 16 + #include <linux/quicklist.h> 16 17 #include <asm/pgalloc.h> 17 18 #include <asm/page.h> 18 19 #include <asm/cacheflush.h> 19 20 20 21 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); 21 - struct kmem_cache *pgd_cache; 22 22 23 23 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 24 24 { ··· 100 100 set_page_private(next, (unsigned long) pprev); 101 101 } 102 102 103 - void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) 103 + void pgd_ctor(void *pgd) 104 104 { 105 105 unsigned long flags; 106 106 ··· 120 120 } 121 121 122 122 /* never called when PTRS_PER_PMD > 1 */ 123 - void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) 123 + void pgd_dtor(void *pgd) 124 124 { 125 125 unsigned long flags; /* can be called from interrupt context */ 126 126 ··· 133 133 { 134 134 pgd_t *pgd; 135 135 136 - pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL); 136 + pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); 137 137 if (!pgd) 138 138 return pgd; 139 139 ··· 143 143 void pgd_free(pgd_t *pgd) 144 144 { 145 145 /* in the non-PAE case, clear_page_tables() clears user pgd entries */ 146 - kmem_cache_free(pgd_cache, pgd); 146 + quicklist_free(0, pgd_dtor, pgd); 147 147 } 148 148 149 149 void __init pgtable_cache_init(void) 150 150 { 151 - pgd_cache = kmem_cache_create("pgd", 152 - PTRS_PER_PGD * sizeof(pgd_t), 153 - PTRS_PER_PGD * sizeof(pgd_t), 154 - SLAB_PANIC, 155 - pgd_ctor, 156 - pgd_dtor); 157 151 } 152 + 153 + void check_pgt_cache(void) 154 + { 155 + quicklist_trim(0, pgd_dtor, 25, 16); 156 + } 157 +
+4
include/asm-frv/tlb.h
··· 3 3 4 4 #include <asm/tlbflush.h> 5 5 6 + #ifdef CONFIG_MMU 7 + extern void check_pgt_cache(void); 8 + #else 6 9 #define check_pgt_cache() do {} while(0) 10 + #endif 7 11 8 12 /* 9 13 * we don't need any special per-pte or per-vma handling...