Index: linux-2.6.21-rc1/mm/slub.c =================================================================== --- linux-2.6.21-rc1.orig/mm/slub.c 2007-02-25 22:26:15.000000000 -0800 +++ linux-2.6.21-rc1/mm/slub.c 2007-02-26 15:34:11.000000000 -0800 @@ -534,6 +534,12 @@ putback_slab(s, page); } +static void flush_slab(struct kmem_cache *s, struct page *page, int cpu) +{ + slab_lock(page); + deactivate_slab(s, page, cpu); +} + /* * Flush cpu slab. * Called from IPI handler with interrupts disabled. @@ -542,10 +548,8 @@ { struct page *page = s->cpu_slab[cpu]; - if (likely(page)) { - slab_lock(page); - deactivate_slab(s, page, cpu); - } + if (likely(page)) + flush_slab(s, page, cpu); } static void flush_cpu_slab(void *d) @@ -560,22 +564,18 @@ /* * Called from IPI to check and flush cpu slabs. */ -static void check_flush_cpu_slab(void *d) +static void check_flush_cpu_slab(void *private) { - struct kmem_cache *s = d; + struct kmem_cache *s = private; int cpu = smp_processor_id(); struct page *page = s->cpu_slab[cpu]; - if (!page) - return; - - if (PageReferenced(page)) { - ClearPageReferenced(page); - atomic_inc(&s->cpu_slabs); - } else { - slab_lock(page); - deactivate_slab(s, page, cpu); + if (page) { + if (!TestClearPageReferenced(page)) + return; + flush_slab(s, page, cpu); } + atomic_dec(&s->cpu_slabs); } /* @@ -591,7 +591,7 @@ atomic_set(&s->cpu_slabs, num_online_cpus()); on_each_cpu(check_flush_cpu_slab, s, 1, 1); if (atomic_read(&s->cpu_slabs)) - schedule_delayed_work(&s->flush, 2 * HZ); + schedule_delayed_work(&s->flush, 30 * HZ); mutex_unlock(&s->flushing); } @@ -687,7 +687,7 @@ #ifdef CONFIG_SMP if (keventd_up() && !atomic_read(&s->cpu_slabs)) { atomic_inc(&s->cpu_slabs); - schedule_delayed_work(&s->flush, 2 * HZ); + schedule_delayed_work(&s->flush, 30 * HZ); } #endif goto redo; Index: linux-2.6.21-rc1/include/linux/slub_def.h =================================================================== --- linux-2.6.21-rc1.orig/include/linux/slub_def.h 2007-02-25 22:00:05.000000000 -0800 +++ linux-2.6.21-rc1/include/linux/slub_def.h 2007-02-26 13:49:17.000000000 -0800 @@ -38,10 +38,15 @@ struct list_head list; /* List of slabs */ #ifdef CONFIG_SMP struct mutex flushing; - atomic_t cpu_slabs; /* if >0 then flusher is scheduled */ + atomic_t cpu_slabs; /* + *if >0 then flusher is scheduled. Also used + * to count remaining cpus if flushing + */ struct delayed_work flush; #endif +#ifdef CONFIG_NUMA struct kmem_cache_node *node[MAX_NUMNODES]; +#endif struct page *cpu_slab[NR_CPUS]; };