diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-06-11 16:23:19 +0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2009-06-11 20:03:30 +0400 |
commit | 89219d37a2377c44fde7bff0bf0623453c05329a (patch) | |
tree | 8183d7bb948f06868e3687b59336c8a99360ce7b /mm/vmalloc.c | |
parent | 06f22f13f3cc2eff00db09f053218e5d4b757bc8 (diff) | |
download | linux-89219d37a2377c44fde7bff0bf0623453c05329a.tar.xz |
kmemleak: Add the vmalloc memory allocation/freeing hooks
This patch adds the callbacks to kmemleak_(alloc|free) functions from
vmalloc/vfree.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 083716ea38c9..b7db93572797 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -25,6 +25,7 @@ #include <linux/rcupdate.h> #include <linux/bootmem.h> #include <linux/pfn.h> +#include <linux/kmemleak.h> #include <asm/atomic.h> #include <asm/uaccess.h> @@ -1327,6 +1328,9 @@ static void __vunmap(const void *addr, int deallocate_pages) void vfree(const void *addr) { BUG_ON(in_interrupt()); + + kmemleak_free(addr); + __vunmap(addr, 1); } EXPORT_SYMBOL(vfree); @@ -1439,8 +1443,17 @@ fail: void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) { - return __vmalloc_area_node(area, gfp_mask, prot, -1, - __builtin_return_address(0)); + void *addr = __vmalloc_area_node(area, gfp_mask, prot, -1, + __builtin_return_address(0)); + + /* + * A ref_count = 3 is needed because the vm_struct and vmap_area + * structures allocated in the __get_vm_area_node() function contain + * references to the virtual address of the vmalloc'ed block. + */ + kmemleak_alloc(addr, area->size - PAGE_SIZE, 3, gfp_mask); + + return addr; } /** @@ -1459,6 +1472,8 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, int node, void *caller) { struct vm_struct *area; + void *addr; + unsigned long real_size = size; size = PAGE_ALIGN(size); if (!size || (size >> PAGE_SHIFT) > num_physpages) @@ -1470,7 +1485,16 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, if (!area) return NULL; - return __vmalloc_area_node(area, gfp_mask, prot, node, caller); + addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); + + /* + * A ref_count = 3 is needed because the vm_struct and vmap_area + * structures allocated in the __get_vm_area_node() function contain + * references to the virtual address of the vmalloc'ed block. + */ + kmemleak_alloc(addr, real_size, 3, gfp_mask); + + return addr; } void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) |