diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2013-11-12 18:07:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 22:09:07 -0500 |
commit | 7f88f88f83ed609650a01b18572e605ea50cd163 (patch) | |
tree | 7a515679de2418dbf006bdc40c23b8c6f6b73fce /mm/vmalloc.c | |
parent | 81556b02525181e19ef073a798ba9d48db96f708 (diff) |
mm: kmemleak: avoid false negatives on vmalloc'ed objects
Commit 248ac0e1943a ("mm/vmalloc: remove guard page from between vmap
blocks") had the side effect of making vmap_area.va_end member point to
the next vmap_area.va_start. This was creating an artificial reference
to vmalloc'ed objects and kmemleak was rarely reporting vmalloc() leaks.
This patch marks the vmap_area containing pointers explicitly and
reduces the min ref_count to 2 as vm_struct still contains a reference
to the vmalloc'ed object. The kmemleak add_scan_area() function has
been improved to allow a SIZE_MAX argument covering the rest of the
object (for simpler calling sites).
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 745fa9567475..0fdf96803c5b 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -359,6 +359,12 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, | |||
359 | if (unlikely(!va)) | 359 | if (unlikely(!va)) |
360 | return ERR_PTR(-ENOMEM); | 360 | return ERR_PTR(-ENOMEM); |
361 | 361 | ||
362 | /* | ||
363 | * Only scan the relevant parts containing pointers to other objects | ||
364 | * to avoid false negatives. | ||
365 | */ | ||
366 | kmemleak_scan_area(&va->rb_node, SIZE_MAX, gfp_mask & GFP_RECLAIM_MASK); | ||
367 | |||
362 | retry: | 368 | retry: |
363 | spin_lock(&vmap_area_lock); | 369 | spin_lock(&vmap_area_lock); |
364 | /* | 370 | /* |
@@ -1645,11 +1651,11 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, | |||
1645 | clear_vm_uninitialized_flag(area); | 1651 | clear_vm_uninitialized_flag(area); |
1646 | 1652 | ||
1647 | /* | 1653 | /* |
1648 | * A ref_count = 3 is needed because the vm_struct and vmap_area | 1654 | * A ref_count = 2 is needed because vm_struct allocated in |
1649 | * structures allocated in the __get_vm_area_node() function contain | 1655 | * __get_vm_area_node() contains a reference to the virtual address of |
1650 | * references to the virtual address of the vmalloc'ed block. | 1656 | * the vmalloc'ed block. |
1651 | */ | 1657 | */ |
1652 | kmemleak_alloc(addr, real_size, 3, gfp_mask); | 1658 | kmemleak_alloc(addr, real_size, 2, gfp_mask); |
1653 | 1659 | ||
1654 | return addr; | 1660 | return addr; |
1655 | 1661 | ||