diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-06-11 08:23:19 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2009-06-11 12:03:30 -0400 |
commit | 89219d37a2377c44fde7bff0bf0623453c05329a (patch) | |
tree | 8183d7bb948f06868e3687b59336c8a99360ce7b /mm | |
parent | 06f22f13f3cc2eff00db09f053218e5d4b757bc8 (diff) |
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')
-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 @@ | |||
25 | #include <linux/rcupdate.h> | 25 | #include <linux/rcupdate.h> |
26 | #include <linux/bootmem.h> | 26 | #include <linux/bootmem.h> |
27 | #include <linux/pfn.h> | 27 | #include <linux/pfn.h> |
28 | #include <linux/kmemleak.h> | ||
28 | 29 | ||
29 | #include <asm/atomic.h> | 30 | #include <asm/atomic.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -1327,6 +1328,9 @@ static void __vunmap(const void *addr, int deallocate_pages) | |||
1327 | void vfree(const void *addr) | 1328 | void vfree(const void *addr) |
1328 | { | 1329 | { |
1329 | BUG_ON(in_interrupt()); | 1330 | BUG_ON(in_interrupt()); |
1331 | |||
1332 | kmemleak_free(addr); | ||
1333 | |||
1330 | __vunmap(addr, 1); | 1334 | __vunmap(addr, 1); |
1331 | } | 1335 | } |
1332 | EXPORT_SYMBOL(vfree); | 1336 | EXPORT_SYMBOL(vfree); |
@@ -1439,8 +1443,17 @@ fail: | |||
1439 | 1443 | ||
1440 | void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) | 1444 | void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) |
1441 | { | 1445 | { |
1442 | return __vmalloc_area_node(area, gfp_mask, prot, -1, | 1446 | void *addr = __vmalloc_area_node(area, gfp_mask, prot, -1, |
1443 | __builtin_return_address(0)); | 1447 | __builtin_return_address(0)); |
1448 | |||
1449 | /* | ||
1450 | * A ref_count = 3 is needed because the vm_struct and vmap_area | ||
1451 | * structures allocated in the __get_vm_area_node() function contain | ||
1452 | * references to the virtual address of the vmalloc'ed block. | ||
1453 | */ | ||
1454 | kmemleak_alloc(addr, area->size - PAGE_SIZE, 3, gfp_mask); | ||
1455 | |||
1456 | return addr; | ||
1444 | } | 1457 | } |
1445 | 1458 | ||
1446 | /** | 1459 | /** |
@@ -1459,6 +1472,8 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | |||
1459 | int node, void *caller) | 1472 | int node, void *caller) |
1460 | { | 1473 | { |
1461 | struct vm_struct *area; | 1474 | struct vm_struct *area; |
1475 | void *addr; | ||
1476 | unsigned long real_size = size; | ||
1462 | 1477 | ||
1463 | size = PAGE_ALIGN(size); | 1478 | size = PAGE_ALIGN(size); |
1464 | if (!size || (size >> PAGE_SHIFT) > num_physpages) | 1479 | 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, | |||
1470 | if (!area) | 1485 | if (!area) |
1471 | return NULL; | 1486 | return NULL; |
1472 | 1487 | ||
1473 | return __vmalloc_area_node(area, gfp_mask, prot, node, caller); | 1488 | addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); |
1489 | |||
1490 | /* | ||
1491 | * A ref_count = 3 is needed because the vm_struct and vmap_area | ||
1492 | * structures allocated in the __get_vm_area_node() function contain | ||
1493 | * references to the virtual address of the vmalloc'ed block. | ||
1494 | */ | ||
1495 | kmemleak_alloc(addr, real_size, 3, gfp_mask); | ||
1496 | |||
1497 | return addr; | ||
1474 | } | 1498 | } |
1475 | 1499 | ||
1476 | void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) | 1500 | void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) |