aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2010-03-10 18:20:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-12 18:52:28 -0500
commit718a38211bf4375c0a1efad3afbc5dbaef5d33f9 (patch)
treeade6815c619705f0342f98cc8bb39fa3309c81a6
parent9b3a6549b2602ca30f58715a0071e29f9898cae9 (diff)
mm: introduce dump_page() and print symbolic flag names
- introduce dump_page() to print the page info for debugging some error condition. - convert three mm users: bad_page(), print_bad_pte() and memory offline failure. - print an extra field: the symbolic names of page->flags Example dump_page() output: [ 157.521694] page:ffffea0000a7cba8 count:2 mapcount:1 mapping:ffff88001c901791 index:0x147 [ 157.525570] page flags: 0x100000000100068(uptodate|lru|active|swapbacked) Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Alex Chiang <achiang@hp.com> Cc: Rik van Riel <riel@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Mel Gorman <mel@linux.vnet.ibm.com> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/mm.h2
-rw-r--r--mm/memory.c8
-rw-r--r--mm/memory_hotplug.c6
-rw-r--r--mm/page_alloc.c83
4 files changed, 86 insertions, 13 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7f693b272c4a..e70f21beb4b4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1465,5 +1465,7 @@ extern void shake_page(struct page *p, int access);
1465extern atomic_long_t mce_bad_pages; 1465extern atomic_long_t mce_bad_pages;
1466extern int soft_offline_page(struct page *page, int flags); 1466extern int soft_offline_page(struct page *page, int flags);
1467 1467
1468extern void dump_page(struct page *page);
1469
1468#endif /* __KERNEL__ */ 1470#endif /* __KERNEL__ */
1469#endif /* _LINUX_MM_H */ 1471#endif /* _LINUX_MM_H */
diff --git a/mm/memory.c b/mm/memory.c
index 3d9130bd95d0..5b7f2002e54b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -509,12 +509,8 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
509 "BUG: Bad page map in process %s pte:%08llx pmd:%08llx\n", 509 "BUG: Bad page map in process %s pte:%08llx pmd:%08llx\n",
510 current->comm, 510 current->comm,
511 (long long)pte_val(pte), (long long)pmd_val(*pmd)); 511 (long long)pte_val(pte), (long long)pmd_val(*pmd));
512 if (page) { 512 if (page)
513 printk(KERN_ALERT 513 dump_page(page);
514 "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
515 page, (void *)page->flags, page_count(page),
516 page_mapcount(page), page->mapping, page->index);
517 }
518 printk(KERN_ALERT 514 printk(KERN_ALERT
519 "addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n", 515 "addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
520 (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index); 516 (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 78e34e63c7b8..be211a582930 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -688,9 +688,9 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
688 if (page_count(page)) 688 if (page_count(page))
689 not_managed++; 689 not_managed++;
690#ifdef CONFIG_DEBUG_VM 690#ifdef CONFIG_DEBUG_VM
691 printk(KERN_INFO "removing from LRU failed" 691 printk(KERN_ALERT "removing pfn %lx from LRU failed\n",
692 " %lx/%d/%lx\n", 692 pfn);
693 pfn, page_count(page), page->flags); 693 dump_page(page);
694#endif 694#endif
695 } 695 }
696 } 696 }
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 78ce90dd671f..d03c946d5566 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -50,6 +50,7 @@
50#include <linux/kmemleak.h> 50#include <linux/kmemleak.h>
51#include <linux/memory.h> 51#include <linux/memory.h>
52#include <trace/events/kmem.h> 52#include <trace/events/kmem.h>
53#include <linux/ftrace_event.h>
53 54
54#include <asm/tlbflush.h> 55#include <asm/tlbflush.h>
55#include <asm/div64.h> 56#include <asm/div64.h>
@@ -288,10 +289,7 @@ static void bad_page(struct page *page)
288 289
289 printk(KERN_ALERT "BUG: Bad page state in process %s pfn:%05lx\n", 290 printk(KERN_ALERT "BUG: Bad page state in process %s pfn:%05lx\n",
290 current->comm, page_to_pfn(page)); 291 current->comm, page_to_pfn(page));
291 printk(KERN_ALERT 292 dump_page(page);
292 "page:%p flags:%p count:%d mapcount:%d mapping:%p index:%lx\n",
293 page, (void *)page->flags, page_count(page),
294 page_mapcount(page), page->mapping, page->index);
295 293
296 dump_stack(); 294 dump_stack();
297out: 295out:
@@ -5183,3 +5181,80 @@ bool is_free_buddy_page(struct page *page)
5183 return order < MAX_ORDER; 5181 return order < MAX_ORDER;
5184} 5182}
5185#endif 5183#endif
5184
5185static struct trace_print_flags pageflag_names[] = {
5186 {1UL << PG_locked, "locked" },
5187 {1UL << PG_error, "error" },
5188 {1UL << PG_referenced, "referenced" },
5189 {1UL << PG_uptodate, "uptodate" },
5190 {1UL << PG_dirty, "dirty" },
5191 {1UL << PG_lru, "lru" },
5192 {1UL << PG_active, "active" },
5193 {1UL << PG_slab, "slab" },
5194 {1UL << PG_owner_priv_1, "owner_priv_1" },
5195 {1UL << PG_arch_1, "arch_1" },
5196 {1UL << PG_reserved, "reserved" },
5197 {1UL << PG_private, "private" },
5198 {1UL << PG_private_2, "private_2" },
5199 {1UL << PG_writeback, "writeback" },
5200#ifdef CONFIG_PAGEFLAGS_EXTENDED
5201 {1UL << PG_head, "head" },
5202 {1UL << PG_tail, "tail" },
5203#else
5204 {1UL << PG_compound, "compound" },
5205#endif
5206 {1UL << PG_swapcache, "swapcache" },
5207 {1UL << PG_mappedtodisk, "mappedtodisk" },
5208 {1UL << PG_reclaim, "reclaim" },
5209 {1UL << PG_buddy, "buddy" },
5210 {1UL << PG_swapbacked, "swapbacked" },
5211 {1UL << PG_unevictable, "unevictable" },
5212#ifdef CONFIG_MMU
5213 {1UL << PG_mlocked, "mlocked" },
5214#endif
5215#ifdef CONFIG_ARCH_USES_PG_UNCACHED
5216 {1UL << PG_uncached, "uncached" },
5217#endif
5218#ifdef CONFIG_MEMORY_FAILURE
5219 {1UL << PG_hwpoison, "hwpoison" },
5220#endif
5221 {-1UL, NULL },
5222};
5223
5224static void dump_page_flags(unsigned long flags)
5225{
5226 const char *delim = "";
5227 unsigned long mask;
5228 int i;
5229
5230 printk(KERN_ALERT "page flags: %#lx(", flags);
5231
5232 /* remove zone id */
5233 flags &= (1UL << NR_PAGEFLAGS) - 1;
5234
5235 for (i = 0; pageflag_names[i].name && flags; i++) {
5236
5237 mask = pageflag_names[i].mask;
5238 if ((flags & mask) != mask)
5239 continue;
5240
5241 flags &= ~mask;
5242 printk("%s%s", delim, pageflag_names[i].name);
5243 delim = "|";
5244 }
5245
5246 /* check for left over flags */
5247 if (flags)
5248 printk("%s%#lx", delim, flags);
5249
5250 printk(")\n");
5251}
5252
5253void dump_page(struct page *page)
5254{
5255 printk(KERN_ALERT
5256 "page:%p count:%d mapcount:%d mapping:%p index:%#lx\n",
5257 page, page_count(page), page_mapcount(page),
5258 page->mapping, page->index);
5259 dump_page_flags(page->flags);
5260}