diff options
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 323513858c20..f8189a4b3e13 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/radix-tree.h> | 24 | #include <linux/radix-tree.h> |
25 | #include <linux/rcupdate.h> | 25 | #include <linux/rcupdate.h> |
26 | #include <linux/pfn.h> | 26 | #include <linux/pfn.h> |
27 | #include <linux/kmemleak.h> | ||
27 | 28 | ||
28 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
@@ -1326,6 +1327,9 @@ static void __vunmap(const void *addr, int deallocate_pages) | |||
1326 | void vfree(const void *addr) | 1327 | void vfree(const void *addr) |
1327 | { | 1328 | { |
1328 | BUG_ON(in_interrupt()); | 1329 | BUG_ON(in_interrupt()); |
1330 | |||
1331 | kmemleak_free(addr); | ||
1332 | |||
1329 | __vunmap(addr, 1); | 1333 | __vunmap(addr, 1); |
1330 | } | 1334 | } |
1331 | EXPORT_SYMBOL(vfree); | 1335 | EXPORT_SYMBOL(vfree); |
@@ -1438,8 +1442,17 @@ fail: | |||
1438 | 1442 | ||
1439 | void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) | 1443 | void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) |
1440 | { | 1444 | { |
1441 | return __vmalloc_area_node(area, gfp_mask, prot, -1, | 1445 | void *addr = __vmalloc_area_node(area, gfp_mask, prot, -1, |
1442 | __builtin_return_address(0)); | 1446 | __builtin_return_address(0)); |
1447 | |||
1448 | /* | ||
1449 | * A ref_count = 3 is needed because the vm_struct and vmap_area | ||
1450 | * structures allocated in the __get_vm_area_node() function contain | ||
1451 | * references to the virtual address of the vmalloc'ed block. | ||
1452 | */ | ||
1453 | kmemleak_alloc(addr, area->size - PAGE_SIZE, 3, gfp_mask); | ||
1454 | |||
1455 | return addr; | ||
1443 | } | 1456 | } |
1444 | 1457 | ||
1445 | /** | 1458 | /** |
@@ -1458,6 +1471,8 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | |||
1458 | int node, void *caller) | 1471 | int node, void *caller) |
1459 | { | 1472 | { |
1460 | struct vm_struct *area; | 1473 | struct vm_struct *area; |
1474 | void *addr; | ||
1475 | unsigned long real_size = size; | ||
1461 | 1476 | ||
1462 | size = PAGE_ALIGN(size); | 1477 | size = PAGE_ALIGN(size); |
1463 | if (!size || (size >> PAGE_SHIFT) > num_physpages) | 1478 | if (!size || (size >> PAGE_SHIFT) > num_physpages) |
@@ -1469,7 +1484,16 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | |||
1469 | if (!area) | 1484 | if (!area) |
1470 | return NULL; | 1485 | return NULL; |
1471 | 1486 | ||
1472 | return __vmalloc_area_node(area, gfp_mask, prot, node, caller); | 1487 | addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); |
1488 | |||
1489 | /* | ||
1490 | * A ref_count = 3 is needed because the vm_struct and vmap_area | ||
1491 | * structures allocated in the __get_vm_area_node() function contain | ||
1492 | * references to the virtual address of the vmalloc'ed block. | ||
1493 | */ | ||
1494 | kmemleak_alloc(addr, real_size, 3, gfp_mask); | ||
1495 | |||
1496 | return addr; | ||
1473 | } | 1497 | } |
1474 | 1498 | ||
1475 | void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) | 1499 | void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) |