Subject: [i386] Band-Aid: Minimal patch to enable SLUB This patch switches the pgd handling to use a quicklist. That way both are disentangled and SLUB works fine (been working with this patch for more than a week on my workstation now ...) Tried to be as least invasive as possible to provide some band aid. Signed-off-by: Christoph Lameter Index: linux-2.6.21-rc7-mm2/arch/i386/mm/init.c =================================================================== --- linux-2.6.21-rc7-mm2.orig/arch/i386/mm/init.c 2007-04-26 11:39:29.000000000 -0700 +++ linux-2.6.21-rc7-mm2/arch/i386/mm/init.c 2007-04-26 11:52:09.000000000 -0700 @@ -752,7 +752,6 @@ int remove_memory(u64 start, u64 size) EXPORT_SYMBOL_GPL(remove_memory); #endif -struct kmem_cache *pgd_cache; struct kmem_cache *pmd_cache; void __init pgtable_cache_init(void) @@ -776,12 +775,6 @@ void __init pgtable_cache_init(void) pgd_size = PAGE_SIZE; } } - pgd_cache = kmem_cache_create("pgd", - pgd_size, - pgd_size, - SLAB_PANIC, - pgd_ctor, - (!SHARED_KERNEL_PMD) ? pgd_dtor : NULL); } /* Index: linux-2.6.21-rc7-mm2/arch/i386/mm/pgtable.c =================================================================== --- linux-2.6.21-rc7-mm2.orig/arch/i386/mm/pgtable.c 2007-04-26 11:39:29.000000000 -0700 +++ linux-2.6.21-rc7-mm2/arch/i386/mm/pgtable.c 2007-04-26 11:51:30.000000000 -0700 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -321,7 +306,7 @@ static void pmd_cache_free(pmd_t *pmd, i pgd_t *pgd_alloc(struct mm_struct *mm) { int i; - pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL); + pgd_t *pgd = quicklist_alloc(QUICK_PGD, GFP_KERNEL, pgd_ctor); if (PTRS_PER_PMD == 1 || !pgd) return pgd; @@ -344,7 +329,7 @@ out_oom: paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); pmd_cache_free(pmd, i); } - kmem_cache_free(pgd_cache, pgd); + quicklist_free(QUICK_PGD, pgd_dtor, pgd); return NULL; } @@ -361,5 +346,11 @@ void pgd_free(pgd_t *pgd) pmd_cache_free(pmd, i); } /* in the non-PAE case, free_pgtables() clears user pgd entries */ - kmem_cache_free(pgd_cache, pgd); + quicklist_free(QUICK_PGD, pgd_dtor, pgd); +} + +void check_pgt_cache(void) +{ + quicklist_trim(QUICK_PGD, pgd_dtor, 25, 16); } + Index: linux-2.6.21-rc7-mm2/arch/i386/Kconfig =================================================================== --- linux-2.6.21-rc7-mm2.orig/arch/i386/Kconfig 2007-04-26 11:39:29.000000000 -0700 +++ linux-2.6.21-rc7-mm2/arch/i386/Kconfig 2007-04-26 11:51:30.000000000 -0700 @@ -55,6 +55,10 @@ config ZONE_DMA bool default y +config QUICKLIST + bool + default y + config SBUS bool @@ -79,10 +83,6 @@ config ARCH_MAY_HAVE_PC_FDC bool default y -config ARCH_USES_SLAB_PAGE_STRUCT - bool - default y - config DMI bool default y Index: linux-2.6.21-rc7-mm2/arch/i386/kernel/process.c =================================================================== --- linux-2.6.21-rc7-mm2.orig/arch/i386/kernel/process.c 2007-04-26 11:39:29.000000000 -0700 +++ linux-2.6.21-rc7-mm2/arch/i386/kernel/process.c 2007-04-26 11:51:30.000000000 -0700 @@ -186,6 +186,7 @@ void cpu_idle(void) if (__get_cpu_var(cpu_idle_state)) __get_cpu_var(cpu_idle_state) = 0; + check_pgt_cache(); rmb(); idle = pm_idle; Index: linux-2.6.21-rc7-mm2/include/asm-i386/pgalloc.h =================================================================== --- linux-2.6.21-rc7-mm2.orig/include/asm-i386/pgalloc.h 2007-04-26 11:39:31.000000000 -0700 +++ linux-2.6.21-rc7-mm2/include/asm-i386/pgalloc.h 2007-04-26 11:51:30.000000000 -0700 @@ -65,6 +65,6 @@ do { \ #define pud_populate(mm, pmd, pte) BUG() #endif -#define check_pgt_cache() do { } while (0) +extern void check_pgt_cache(void); #endif /* _I386_PGALLOC_H */ Index: linux-2.6.21-rc7-mm2/arch/i386/kernel/smp.c =================================================================== --- linux-2.6.21-rc7-mm2.orig/arch/i386/kernel/smp.c 2007-04-26 11:39:29.000000000 -0700 +++ linux-2.6.21-rc7-mm2/arch/i386/kernel/smp.c 2007-04-26 11:51:30.000000000 -0700 @@ -429,7 +429,7 @@ void flush_tlb_mm (struct mm_struct * mm } if (!cpus_empty(cpu_mask)) flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); - + check_pgt_cache(); preempt_enable(); }