The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mm/debug-pagealloc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include <linux/kernel.h>
    2 #include <linux/string.h>
    3 #include <linux/mm.h>
    4 #include <linux/highmem.h>
    5 #include <linux/page-debug-flags.h>
    6 #include <linux/poison.h>
    7 #include <linux/ratelimit.h>
    8 
    9 static inline void set_page_poison(struct page *page)
   10 {
   11         __set_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
   12 }
   13 
   14 static inline void clear_page_poison(struct page *page)
   15 {
   16         __clear_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
   17 }
   18 
   19 static inline bool page_poison(struct page *page)
   20 {
   21         return test_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
   22 }
   23 
   24 static void poison_page(struct page *page)
   25 {
   26         void *addr = kmap_atomic(page);
   27 
   28         set_page_poison(page);
   29         memset(addr, PAGE_POISON, PAGE_SIZE);
   30         kunmap_atomic(addr);
   31 }
   32 
   33 static void poison_pages(struct page *page, int n)
   34 {
   35         int i;
   36 
   37         for (i = 0; i < n; i++)
   38                 poison_page(page + i);
   39 }
   40 
   41 static bool single_bit_flip(unsigned char a, unsigned char b)
   42 {
   43         unsigned char error = a ^ b;
   44 
   45         return error && !(error & (error - 1));
   46 }
   47 
   48 static void check_poison_mem(unsigned char *mem, size_t bytes)
   49 {
   50         static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 10);
   51         unsigned char *start;
   52         unsigned char *end;
   53 
   54         start = memchr_inv(mem, PAGE_POISON, bytes);
   55         if (!start)
   56                 return;
   57 
   58         for (end = mem + bytes - 1; end > start; end--) {
   59                 if (*end != PAGE_POISON)
   60                         break;
   61         }
   62 
   63         if (!__ratelimit(&ratelimit))
   64                 return;
   65         else if (start == end && single_bit_flip(*start, PAGE_POISON))
   66                 printk(KERN_ERR "pagealloc: single bit error\n");
   67         else
   68                 printk(KERN_ERR "pagealloc: memory corruption\n");
   69 
   70         print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
   71                         end - start + 1, 1);
   72         dump_stack();
   73 }
   74 
   75 static void unpoison_page(struct page *page)
   76 {
   77         void *addr;
   78 
   79         if (!page_poison(page))
   80                 return;
   81 
   82         addr = kmap_atomic(page);
   83         check_poison_mem(addr, PAGE_SIZE);
   84         clear_page_poison(page);
   85         kunmap_atomic(addr);
   86 }
   87 
   88 static void unpoison_pages(struct page *page, int n)
   89 {
   90         int i;
   91 
   92         for (i = 0; i < n; i++)
   93                 unpoison_page(page + i);
   94 }
   95 
   96 void kernel_map_pages(struct page *page, int numpages, int enable)
   97 {
   98         if (enable)
   99                 unpoison_pages(page, numpages);
  100         else
  101                 poison_pages(page, numpages);
  102 }

Cache object: 636825729591fc198243e126a2f89d3c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.