Merge branch 'akpm'
[linux-2.6.git] / mm / page_alloc.c
index 2f457a7..a5f3c27 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/bootmem.h>
 #include <linux/compiler.h>
 #include <linux/kernel.h>
+#include <linux/kmemcheck.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
 #include <linux/pagevec.h>
@@ -558,6 +559,8 @@ static void __free_pages_ok(struct page *page, unsigned int order)
        int bad = 0;
        int clearMlocked = PageMlocked(page);
 
+       kmemcheck_free_shadow(page, order);
+
        for (i = 0 ; i < (1 << order) ; ++i)
                bad += free_pages_check(page + i);
        if (bad)
@@ -1020,6 +1023,8 @@ static void free_hot_cold_page(struct page *page, int cold)
        unsigned long flags;
        int clearMlocked = PageMlocked(page);
 
+       kmemcheck_free_shadow(page, 0);
+
        if (PageAnon(page))
                page->mapping = NULL;
        if (free_pages_check(page))
@@ -1076,6 +1081,16 @@ void split_page(struct page *page, unsigned int order)
 
        VM_BUG_ON(PageCompound(page));
        VM_BUG_ON(!page_count(page));
+
+#ifdef CONFIG_KMEMCHECK
+       /*
+        * Split shadow pages too, because free(page[0]) would
+        * otherwise free the whole shadow.
+        */
+       if (kmemcheck_page_is_tracked(page))
+               split_page(virt_to_page(page[0].shadow), order);
+#endif
+
        for (i = 1; i < (1 << order); i++)
                set_page_refcounted(page + i);
 }
@@ -1828,7 +1843,10 @@ nopage:
                dump_stack();
                show_mem();
        }
+       return page;
 got_pg:
+       if (kmemcheck_enabled)
+               kmemcheck_pagealloc_alloc(page, order, gfp_mask);
        return page;
 
 }