aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorVegard Nossum <vegard.nossum@gmail.com>2008-11-25 10:55:53 -0500
committerVegard Nossum <vegard.nossum@gmail.com>2009-06-15 09:48:33 -0400
commitb1eeab67682a5e397aecf172046b3a8bd4808ae4 (patch)
treec357b6ac1945dc8beecc2f8c4d84660ad8d35aae /mm/page_alloc.c
parent9b5cab31897e9e89e36c0c2a89b16b93ff1a971a (diff)
kmemcheck: add hooks for the page allocator
This adds support for tracking the initializedness of memory that was allocated with the page allocator. Highmem requests are not tracked. Cc: Dave Hansen <dave@linux.vnet.ibm.com> Acked-by: Pekka Enberg <penberg@cs.helsinki.fi> [build fix for !CONFIG_KMEMCHECK] Signed-off-by: Ingo Molnar <mingo@elte.hu> [rebased for mainline inclusion] Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 17d5f539a9aa..0727896a88ac 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -23,6 +23,7 @@
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/kmemcheck.h>
26#include <linux/module.h> 27#include <linux/module.h>
27#include <linux/suspend.h> 28#include <linux/suspend.h>
28#include <linux/pagevec.h> 29#include <linux/pagevec.h>
@@ -546,6 +547,8 @@ static void __free_pages_ok(struct page *page, unsigned int order)
546 int i; 547 int i;
547 int bad = 0; 548 int bad = 0;
548 549
550 kmemcheck_free_shadow(page, order);
551
549 for (i = 0 ; i < (1 << order) ; ++i) 552 for (i = 0 ; i < (1 << order) ; ++i)
550 bad += free_pages_check(page + i); 553 bad += free_pages_check(page + i);
551 if (bad) 554 if (bad)
@@ -994,6 +997,8 @@ static void free_hot_cold_page(struct page *page, int cold)
994 struct per_cpu_pages *pcp; 997 struct per_cpu_pages *pcp;
995 unsigned long flags; 998 unsigned long flags;
996 999
1000 kmemcheck_free_shadow(page, 0);
1001
997 if (PageAnon(page)) 1002 if (PageAnon(page))
998 page->mapping = NULL; 1003 page->mapping = NULL;
999 if (free_pages_check(page)) 1004 if (free_pages_check(page))
@@ -1047,6 +1052,16 @@ void split_page(struct page *page, unsigned int order)
1047 1052
1048 VM_BUG_ON(PageCompound(page)); 1053 VM_BUG_ON(PageCompound(page));
1049 VM_BUG_ON(!page_count(page)); 1054 VM_BUG_ON(!page_count(page));
1055
1056#ifdef CONFIG_KMEMCHECK
1057 /*
1058 * Split shadow pages too, because free(page[0]) would
1059 * otherwise free the whole shadow.
1060 */
1061 if (kmemcheck_page_is_tracked(page))
1062 split_page(virt_to_page(page[0].shadow), order);
1063#endif
1064
1050 for (i = 1; i < (1 << order); i++) 1065 for (i = 1; i < (1 << order); i++)
1051 set_page_refcounted(page + i); 1066 set_page_refcounted(page + i);
1052} 1067}
@@ -1667,7 +1682,10 @@ nopage:
1667 dump_stack(); 1682 dump_stack();
1668 show_mem(); 1683 show_mem();
1669 } 1684 }
1685 return page;
1670got_pg: 1686got_pg:
1687 if (kmemcheck_enabled)
1688 kmemcheck_pagealloc_alloc(page, order, gfp_mask);
1671 return page; 1689 return page;
1672} 1690}
1673EXPORT_SYMBOL(__alloc_pages_internal); 1691EXPORT_SYMBOL(__alloc_pages_internal);