Index: linux-2.6.22-rc4-mm2/mm/slub.c =================================================================== --- linux-2.6.22-rc4-mm2.orig/mm/slub.c 2007-06-18 01:34:52.000000000 -0700 +++ linux-2.6.22-rc4-mm2/mm/slub.c 2007-06-18 02:09:15.000000000 -0700 @@ -1612,7 +1612,8 @@ static void __always_inline *slab_alloc( local_irq_save(flags); c = get_cpu_slab(s, smp_processor_id()); - if (unlikely(!c->lockless_freelist || !node_match(c, node))) + BUG_ON(!c); + if (unlikely(!c || !c->lockless_freelist || !node_match(c, node))) object = __slab_alloc(s, gfpflags, node, addr, c); @@ -2003,12 +2004,15 @@ static int alloc_kmem_cache_cpus(struct for_each_online_cpu(cpu) { struct kmem_cache_cpu *c = get_cpu_slab(s, cpu); - if (c) + if (c) { + printk("alloc kmem_cache_cpu %s exists\n", s->name); continue; + } c = alloc_kmem_cache_cpu(cpu, flags); if (!c) { free_kmem_cache_cpus(s); + printk("Failed to init %s cpucache\n", s->name); return 0; } s->cpu_slab[cpu] = c; @@ -2022,7 +2026,7 @@ static void __init init_alloc_cpu(void) int i; for_each_online_cpu(cpu) { - for (i = NR_KMEM_CACHE_CPU - 1; i > 0; i--) + for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--) free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu); } @@ -3241,15 +3245,28 @@ static int __cpuinit slab_cpuup_callback unsigned long flags; switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + down_read(&slub_lock); + list_for_each_entry(s, &slab_caches, list) + s->cpu_slab[cpu] = alloc_kmem_cache_cpu(cpu, + GFP_KERNEL); + up_read(&slub_lock); + break; + case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: down_read(&slub_lock); list_for_each_entry(s, &slab_caches, list) { + struct kmem_cache_cpu *c = get_cpu_slab(s, cpu); + local_irq_save(flags); __flush_cpu_slab(s, cpu); local_irq_restore(flags); + free_kmem_cache_cpu(c, cpu); + s->cpu_slab[cpu] = NULL; } up_read(&slub_lock); break;