]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
debug-pagealloc: add support for highmem pages
authorAkinobu Mita <akinobu.mita@gmail.com>
Wed, 5 Oct 2011 00:43:04 +0000 (11:43 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 7 Oct 2011 06:06:40 +0000 (17:06 +1100)
This adds support for highmem pages poisoning and verification to the
debug-pagealloc feature for no-architecture support.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/debug-pagealloc.c

index 2618933efdb361d974033380b00e5c86f6c31291..bda7ed044eb1c436b363e8ca52206cc73d081d3d 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/highmem.h>
 #include <linux/page-debug-flags.h>
 #include <linux/poison.h>
 #include <linux/ratelimit.h>
@@ -20,28 +21,16 @@ static inline bool page_poison(struct page *page)
        return test_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
 }
 
-static void poison_highpage(struct page *page)
-{
-       /*
-        * Page poisoning for highmem pages is not implemented.
-        *
-        * This can be called from interrupt contexts.
-        * So we need to create a new kmap_atomic slot for this
-        * application and it will need interrupt protection.
-        */
-}
-
 static void poison_page(struct page *page)
 {
        void *addr;
 
-       if (PageHighMem(page)) {
-               poison_highpage(page);
-               return;
-       }
+       preempt_disable();
+       addr = kmap_atomic(page);
        set_page_poison(page);
-       addr = page_address(page);
        memset(addr, PAGE_POISON, PAGE_SIZE);
+       kunmap_atomic(addr);
+       preempt_enable();
 }
 
 static void poison_pages(struct page *page, int n)
@@ -86,27 +75,19 @@ static void check_poison_mem(unsigned char *mem, size_t bytes)
        dump_stack();
 }
 
-static void unpoison_highpage(struct page *page)
-{
-       /*
-        * See comment in poison_highpage().
-        * Highmem pages should not be poisoned for now
-        */
-       BUG_ON(page_poison(page));
-}
-
 static void unpoison_page(struct page *page)
 {
-       if (PageHighMem(page)) {
-               unpoison_highpage(page);
+       void *addr;
+
+       if (!page_poison(page))
                return;
-       }
-       if (page_poison(page)) {
-               void *addr = page_address(page);
 
-               check_poison_mem(addr, PAGE_SIZE);
-               clear_page_poison(page);
-       }
+       preempt_disable();
+       addr = kmap_atomic(page);
+       check_poison_mem(addr, PAGE_SIZE);
+       clear_page_poison(page);
+       kunmap_atomic(addr);
+       preempt_enable();
 }
 
 static void unpoison_pages(struct page *page, int n)