// $Header$ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 6 // SUBLEVEL = 12 // EXTRAVERSION = --- 2.6/mm/slab.c 2005-06-18 15:00:24.000000000 +0200 +++ build-2.6/mm/slab.c 2005-07-02 16:37:52.000000000 +0200 @@ -2642,7 +2642,7 @@ int shared) { struct ccupdate_struct new; - struct array_cache *new_shared; + struct array_cache *new_shared, *old; int i; memset(&new.new,0,sizeof(new.new)); @@ -2677,19 +2677,26 @@ spin_unlock_irq(&cachep->spinlock); kfree(ccold); } - new_shared = alloc_arraycache(-1, batchcount*shared, 0xbaadf00d); - if (new_shared) { - struct array_cache *old; - - spin_lock_irq(&cachep->spinlock); - old = cachep->lists.shared; - cachep->lists.shared = new_shared; - if (old) - free_block(cachep, ac_entry(old), old->avail); - spin_unlock_irq(&cachep->spinlock); - kfree(old); + if (shared > 0) { + new_shared = alloc_arraycache(-1, batchcount*shared, 0xbaadf00d); + /* + * Memory allocation failed - keep shared as it was + */ + if (!new_shared) + goto keep_shared; + } else { + new_shared = NULL; } + spin_lock_irq(&cachep->spinlock); + old = cachep->lists.shared; + cachep->lists.shared = new_shared; + if (old) + free_block(cachep, ac_entry(old), old->avail); + spin_unlock_irq(&cachep->spinlock); + kfree(old); + +keep_shared: return 0; } @@ -2908,6 +2915,7 @@ unsigned long num_objs; unsigned long active_slabs = 0; unsigned long num_slabs; + unsigned int shared_sz, shared_avail; const char *name; char *error = NULL; @@ -2949,11 +2957,17 @@ seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", name, active_objs, num_objs, cachep->objsize, cachep->num, (1<gfporder)); + if (cachep->lists.shared) { + shared_sz = cachep->lists.shared->limit/cachep->batchcount; + shared_avail = cachep->lists.shared->avail; + } else { + shared_sz = 0; + shared_avail = 0; + } seq_printf(m, " : tunables %4u %4u %4u", - cachep->limit, cachep->batchcount, - cachep->lists.shared->limit/cachep->batchcount); + cachep->limit, cachep->batchcount, shared_sz); seq_printf(m, " : slabdata %6lu %6lu %6u", - active_slabs, num_slabs, cachep->lists.shared->avail); + active_slabs, num_slabs, shared_avail); #if STATS { /* list3 stats */ unsigned long high = cachep->high_mark;