aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2016-03-15 17:55:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-15 19:55:16 -0400
commitedf14cdbf9a0e5ab52698ca66d07a76ade0d5c46 (patch)
tree347fa732387b755a485c2d29e50485529e077b8d /mm
parent420adbe9fc1a45187cfa74df9dbfd72272c4e2fa (diff)
mm, printk: introduce new format string for flags
In mm we use several kinds of flags bitfields that are sometimes printed for debugging purposes, or exported to userspace via sysfs. To make them easier to interpret independently on kernel version and config, we want to dump also the symbolic flag names. So far this has been done with repeated calls to pr_cont(), which is unreliable on SMP, and not usable for e.g. sysfs export. To get a more reliable and universal solution, this patch extends printk() format string for pointers to handle the page flags (%pGp), gfp_flags (%pGg) and vma flags (%pGv). Existing users of dump_flag_names() are converted and simplified. It would be possible to pass flags by value instead of pointer, but the %p format string for pointers already has extensions for various kernel structures, so it's a good fit, and the extra indirection in a non-critical path is negligible. [linux@rasmusvillemoes.dk: lots of good implementation suggestions] Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Sasha Levin <sasha.levin@oracle.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Mel Gorman <mgorman@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/debug.c34
-rw-r--r--mm/internal.h6
2 files changed, 26 insertions, 14 deletions
diff --git a/mm/debug.c b/mm/debug.c
index 410af904a7d5..0328fd377545 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -11,12 +11,21 @@
11#include <linux/memcontrol.h> 11#include <linux/memcontrol.h>
12#include <trace/events/mmflags.h> 12#include <trace/events/mmflags.h>
13 13
14static const struct trace_print_flags pageflag_names[] = { 14#include "internal.h"
15 __def_pageflag_names 15
16const struct trace_print_flags pageflag_names[] = {
17 __def_pageflag_names,
18 {0, NULL}
19};
20
21const struct trace_print_flags gfpflag_names[] = {
22 __def_gfpflag_names,
23 {0, NULL}
16}; 24};
17 25
18static const struct trace_print_flags gfpflag_names[] = { 26const struct trace_print_flags vmaflag_names[] = {
19 __def_gfpflag_names 27 __def_vmaflag_names,
28 {0, NULL}
20}; 29};
21 30
22static void dump_flags(unsigned long flags, 31static void dump_flags(unsigned long flags,
@@ -58,14 +67,15 @@ void dump_page_badflags(struct page *page, const char *reason,
58 if (PageCompound(page)) 67 if (PageCompound(page))
59 pr_cont(" compound_mapcount: %d", compound_mapcount(page)); 68 pr_cont(" compound_mapcount: %d", compound_mapcount(page));
60 pr_cont("\n"); 69 pr_cont("\n");
61 BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS); 70 BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1);
62 dump_flags(page->flags, pageflag_names, ARRAY_SIZE(pageflag_names)); 71 dump_flags(page->flags, pageflag_names,
72 ARRAY_SIZE(pageflag_names) - 1);
63 if (reason) 73 if (reason)
64 pr_alert("page dumped because: %s\n", reason); 74 pr_alert("page dumped because: %s\n", reason);
65 if (page->flags & badflags) { 75 if (page->flags & badflags) {
66 pr_alert("bad because of flags:\n"); 76 pr_alert("bad because of flags:\n");
67 dump_flags(page->flags & badflags, 77 dump_flags(page->flags & badflags, pageflag_names,
68 pageflag_names, ARRAY_SIZE(pageflag_names)); 78 ARRAY_SIZE(pageflag_names) - 1);
69 } 79 }
70#ifdef CONFIG_MEMCG 80#ifdef CONFIG_MEMCG
71 if (page->mem_cgroup) 81 if (page->mem_cgroup)
@@ -81,10 +91,6 @@ EXPORT_SYMBOL(dump_page);
81 91
82#ifdef CONFIG_DEBUG_VM 92#ifdef CONFIG_DEBUG_VM
83 93
84static const struct trace_print_flags vmaflag_names[] = {
85 __def_vmaflag_names
86};
87
88void dump_vma(const struct vm_area_struct *vma) 94void dump_vma(const struct vm_area_struct *vma)
89{ 95{
90 pr_emerg("vma %p start %p end %p\n" 96 pr_emerg("vma %p start %p end %p\n"
@@ -96,7 +102,7 @@ void dump_vma(const struct vm_area_struct *vma)
96 (unsigned long)pgprot_val(vma->vm_page_prot), 102 (unsigned long)pgprot_val(vma->vm_page_prot),
97 vma->anon_vma, vma->vm_ops, vma->vm_pgoff, 103 vma->anon_vma, vma->vm_ops, vma->vm_pgoff,
98 vma->vm_file, vma->vm_private_data); 104 vma->vm_file, vma->vm_private_data);
99 dump_flags(vma->vm_flags, vmaflag_names, ARRAY_SIZE(vmaflag_names)); 105 dump_flags(vma->vm_flags, vmaflag_names, ARRAY_SIZE(vmaflag_names) - 1);
100} 106}
101EXPORT_SYMBOL(dump_vma); 107EXPORT_SYMBOL(dump_vma);
102 108
@@ -168,7 +174,7 @@ void dump_mm(const struct mm_struct *mm)
168 ); 174 );
169 175
170 dump_flags(mm->def_flags, vmaflag_names, 176 dump_flags(mm->def_flags, vmaflag_names,
171 ARRAY_SIZE(vmaflag_names)); 177 ARRAY_SIZE(vmaflag_names) - 1);
172} 178}
173 179
174#endif /* CONFIG_DEBUG_VM */ 180#endif /* CONFIG_DEBUG_VM */
diff --git a/mm/internal.h b/mm/internal.h
index a38a21ebddb4..6636e1d3ecf0 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -14,6 +14,7 @@
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/tracepoint-defs.h>
17 18
18/* 19/*
19 * The set of flags that only affect watermark checking and reclaim 20 * The set of flags that only affect watermark checking and reclaim
@@ -466,4 +467,9 @@ static inline void try_to_unmap_flush_dirty(void)
466} 467}
467 468
468#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */ 469#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
470
471extern const struct trace_print_flags pageflag_names[];
472extern const struct trace_print_flags vmaflag_names[];
473extern const struct trace_print_flags gfpflag_names[];
474
469#endif /* __MM_INTERNAL_H */ 475#endif /* __MM_INTERNAL_H */