Commit 09f95761 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] slab: additional debug checks

From: Manfred Spraul <manfred@colorfullife.com>

below is the promised patch for better slab debugging, against 2.5.68-mm4:

Changes:

- enable redzoning and last user accounting even for large objects, if
  that doesn't waste too much memory

- document why FORCED_DEBUG doesn't enable redzoning&last user accounting
  for some caches.

- check the validity of the bufctl chains in a slab in __free_blocks.
  This detects double-free error for the caches without redzoning.
parent f31fd780
...@@ -940,12 +940,19 @@ kmem_cache_create (const char *name, size_t size, size_t offset, ...@@ -940,12 +940,19 @@ kmem_cache_create (const char *name, size_t size, size_t offset,
} }
#if FORCED_DEBUG #if FORCED_DEBUG
if ((size < (PAGE_SIZE>>3)) && !(flags & SLAB_MUST_HWCACHE_ALIGN))
/* /*
* do not red zone large object, causes severe * Enable redzoning and last user accounting, except
* fragmentation. * - for caches with forced alignment: redzoning would violate the
*/ * alignment
* - for caches with large objects, if the increased size would
* increase the object size above the next power of two: caches
* with object sizes just above a power of two have a significant
* amount of internal fragmentation
*/
if ((size < (PAGE_SIZE>>3) || fls(size-1) == fls(size-1+3*BYTES_PER_WORD))
&& !(flags & SLAB_MUST_HWCACHE_ALIGN)) {
flags |= SLAB_RED_ZONE|SLAB_STORE_USER; flags |= SLAB_RED_ZONE|SLAB_STORE_USER;
}
flags |= SLAB_POISON; flags |= SLAB_POISON;
#endif #endif
#endif #endif
...@@ -1782,10 +1789,12 @@ __free_block(kmem_cache_t *cachep, void **objpp, int nr_objects) ...@@ -1782,10 +1789,12 @@ __free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
slabp = GET_PAGE_SLAB(virt_to_page(objp)); slabp = GET_PAGE_SLAB(virt_to_page(objp));
list_del(&slabp->list); list_del(&slabp->list);
objnr = (objp - slabp->s_mem) / cachep->objsize; objnr = (objp - slabp->s_mem) / cachep->objsize;
check_slabp(cachep, slabp);
slab_bufctl(slabp)[objnr] = slabp->free; slab_bufctl(slabp)[objnr] = slabp->free;
slabp->free = objnr; slabp->free = objnr;
STATS_DEC_ACTIVE(cachep); STATS_DEC_ACTIVE(cachep);
slabp->inuse--; slabp->inuse--;
check_slabp(cachep, slabp);
/* fixup slab chains */ /* fixup slab chains */
if (slabp->inuse == 0) { if (slabp->inuse == 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment