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 <clameter@sgi.com>

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 <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
+#include <linux/quicklist.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -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();
 }