|
@@ -50,6 +50,7 @@
|
|
|
#include <linux/kmemleak.h>
|
|
|
#include <linux/memory.h>
|
|
|
#include <trace/events/kmem.h>
|
|
|
+#include <linux/ftrace_event.h>
|
|
|
|
|
|
#include <asm/tlbflush.h>
|
|
|
#include <asm/div64.h>
|
|
@@ -288,10 +289,7 @@ static void bad_page(struct page *page)
|
|
|
|
|
|
printk(KERN_ALERT "BUG: Bad page state in process %s pfn:%05lx\n",
|
|
|
current->comm, page_to_pfn(page));
|
|
|
- printk(KERN_ALERT
|
|
|
- "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
|
|
|
- page, (void *)page->flags, page_count(page),
|
|
|
- page_mapcount(page), page->mapping, page->index);
|
|
|
+ dump_page(page);
|
|
|
|
|
|
dump_stack();
|
|
|
out:
|
|
@@ -5183,3 +5181,80 @@ bool is_free_buddy_page(struct page *page)
|
|
|
return order < MAX_ORDER;
|
|
|
}
|
|
|
#endif
|
|
|
+
|
|
|
+static struct trace_print_flags pageflag_names[] = {
|
|
|
+ {1UL << PG_locked, "locked" },
|
|
|
+ {1UL << PG_error, "error" },
|
|
|
+ {1UL << PG_referenced, "referenced" },
|
|
|
+ {1UL << PG_uptodate, "uptodate" },
|
|
|
+ {1UL << PG_dirty, "dirty" },
|
|
|
+ {1UL << PG_lru, "lru" },
|
|
|
+ {1UL << PG_active, "active" },
|
|
|
+ {1UL << PG_slab, "slab" },
|
|
|
+ {1UL << PG_owner_priv_1, "owner_priv_1" },
|
|
|
+ {1UL << PG_arch_1, "arch_1" },
|
|
|
+ {1UL << PG_reserved, "reserved" },
|
|
|
+ {1UL << PG_private, "private" },
|
|
|
+ {1UL << PG_private_2, "private_2" },
|
|
|
+ {1UL << PG_writeback, "writeback" },
|
|
|
+#ifdef CONFIG_PAGEFLAGS_EXTENDED
|
|
|
+ {1UL << PG_head, "head" },
|
|
|
+ {1UL << PG_tail, "tail" },
|
|
|
+#else
|
|
|
+ {1UL << PG_compound, "compound" },
|
|
|
+#endif
|
|
|
+ {1UL << PG_swapcache, "swapcache" },
|
|
|
+ {1UL << PG_mappedtodisk, "mappedtodisk" },
|
|
|
+ {1UL << PG_reclaim, "reclaim" },
|
|
|
+ {1UL << PG_buddy, "buddy" },
|
|
|
+ {1UL << PG_swapbacked, "swapbacked" },
|
|
|
+ {1UL << PG_unevictable, "unevictable" },
|
|
|
+#ifdef CONFIG_MMU
|
|
|
+ {1UL << PG_mlocked, "mlocked" },
|
|
|
+#endif
|
|
|
+#ifdef CONFIG_ARCH_USES_PG_UNCACHED
|
|
|
+ {1UL << PG_uncached, "uncached" },
|
|
|
+#endif
|
|
|
+#ifdef CONFIG_MEMORY_FAILURE
|
|
|
+ {1UL << PG_hwpoison, "hwpoison" },
|
|
|
+#endif
|
|
|
+ {-1UL, NULL },
|
|
|
+};
|
|
|
+
|
|
|
+static void dump_page_flags(unsigned long flags)
|
|
|
+{
|
|
|
+ const char *delim = "";
|
|
|
+ unsigned long mask;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ printk(KERN_ALERT "page flags: %#lx(", flags);
|
|
|
+
|
|
|
+ /* remove zone id */
|
|
|
+ flags &= (1UL << NR_PAGEFLAGS) - 1;
|
|
|
+
|
|
|
+ for (i = 0; pageflag_names[i].name && flags; i++) {
|
|
|
+
|
|
|
+ mask = pageflag_names[i].mask;
|
|
|
+ if ((flags & mask) != mask)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ flags &= ~mask;
|
|
|
+ printk("%s%s", delim, pageflag_names[i].name);
|
|
|
+ delim = "|";
|
|
|
+ }
|
|
|
+
|
|
|
+ /* check for left over flags */
|
|
|
+ if (flags)
|
|
|
+ printk("%s%#lx", delim, flags);
|
|
|
+
|
|
|
+ printk(")\n");
|
|
|
+}
|
|
|
+
|
|
|
+void dump_page(struct page *page)
|
|
|
+{
|
|
|
+ printk(KERN_ALERT
|
|
|
+ "page:%p count:%d mapcount:%d mapping:%p index:%#lx\n",
|
|
|
+ page, page_count(page), page_mapcount(page),
|
|
|
+ page->mapping, page->index);
|
|
|
+ dump_page_flags(page->flags);
|
|
|
+}
|