Re: Tracing memory leaks (slabs) in 2.6.9+ kernels?

From: Manfred Spraul
Date: Wed Mar 02 2005 - 15:48:42 EST


Andrew Morton wrote:

OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx> wrote:


Andrew Morton <akpm@xxxxxxxx> writes:

> + slab_bufctl(slabp)[objnr] = (unsigned long)caller;

Umm... this patch looks strange..

slab_bufctl() returns "kmem_bufctl_t *", but kmem_bufctl_t is
"unsigned short".



Good point. This seems to work.



Two updates are needed for the leak detection in recent kernels:
- set kmem_bufctl_t back to unsigned long
- relax the check in check_slabuse, something like the attached patch.

Note that the patch is not tested.

--
Manfred
--- 2.6/mm/slab.c 2005-03-02 20:44:47.738737171 +0100
+++ build-2.6/mm/slab.c 2005-03-02 20:44:15.290618759 +0100
@@ -2645,18 +2642,10 @@
red1 = *dbg_redzone1(cachep, objp);
red2 = *dbg_redzone2(cachep, objp);

- /* simplest case: marked as inactive */
- if (red1 == RED_INACTIVE && red2 == RED_INACTIVE)
- continue;
-
- /* tricky case: if the bufctl value is BUFCTL_ALLOC, then
- * the object is either allocated or somewhere in a cpu
- * cache. The cpu caches are lockless and there might be
- * a concurrent alloc/free call, thus we must accept random
- * combinations of RED_ACTIVE and _INACTIVE
+ /* leak detection stores the caller address in the bufctl,
+ * thus random combinations of active and inactive are ok
*/
- if (slab_bufctl(slabp)[i] == BUFCTL_ALLOC &&
- (red1 == RED_INACTIVE || red1 == RED_ACTIVE) &&
+ if ((red1 == RED_INACTIVE || red1 == RED_ACTIVE) &&
(red2 == RED_INACTIVE || red2 == RED_ACTIVE))
continue;