Message ID | 20230123170419.7292-10-george@enfabrica.net (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mm: kmemleak: fix unreported memory leaks | expand |
On Mon, Jan 23, 2023 at 11:04:19AM -0600, George Prekas wrote: > If kmalloc returns a page aligned object, then the object has 2 > references: the pointer returned by kmalloc and page->s_mem of the first > page of the object. Account for this extra reference, so that kmemleak > can correctly detect leaks for page aligned objects. Is this true for multi-page slabs? Imagine if you allocate objects of size 4kB. Slab/Slub will allocate slabs of size 32kB and try to allocate 8 objects from each slab. Only the first one will have an s_mem pointing into it. No? > - kmemleak_alloc_recursive(p[i], s->object_size, 1, > + min_count = 1; > + /* If p[i] is page aligned, then a page->s_mem refers to it. */ Also this comment should read 'slab->s_mem'. Individual pages within the slab do not have s_mem pointers, only the slab. > + if (((uintptr_t)p[i] & ~PAGE_MASK) == 0) > + min_count++; > + kmemleak_alloc_recursive(p[i], s->object_size, min_count, > s->flags, flags);
On Mon, 23 Jan 2023, George Prekas wrote: > If kmalloc returns a page aligned object, then the object has 2 > references: the pointer returned by kmalloc and page->s_mem of the first > page of the object. Account for this extra reference, so that kmemleak > can correctly detect leaks for page aligned objects. s_mem is a reference to the array of slab objects in a SLAB page. It is not referring to a particular object. s_mem allows access to the Nth object in a slab page. See the function index_to_obj() in slab.c static inline void *index_to_obj(struct kmem_cache *cache, const struct slab *slab, unsigned int idx) { return slab->s_mem + cache->size * idx; }
diff --git a/mm/slab.h b/mm/slab.h index 7cc432969945..76341c7c048e 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -734,6 +734,7 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, unsigned int orig_size) { unsigned int zero_size = s->object_size; + int min_count; size_t i; flags &= gfp_allowed_mask; @@ -761,7 +762,11 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, p[i] = kasan_slab_alloc(s, p[i], flags, init); if (p[i] && init && !kasan_has_integrated_init()) memset(p[i], 0, zero_size); - kmemleak_alloc_recursive(p[i], s->object_size, 1, + min_count = 1; + /* If p[i] is page aligned, then a page->s_mem refers to it. */ + if (((uintptr_t)p[i] & ~PAGE_MASK) == 0) + min_count++; + kmemleak_alloc_recursive(p[i], s->object_size, min_count, s->flags, flags); kmsan_slab_alloc(s, p[i], flags); }
If kmalloc returns a page aligned object, then the object has 2 references: the pointer returned by kmalloc and page->s_mem of the first page of the object. Account for this extra reference, so that kmemleak can correctly detect leaks for page aligned objects. Signed-off-by: George Prekas <george@enfabrica.net> --- mm/slab.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)