diff options
author | Vlastimil Babka <vbabka@suse.cz> | 2016-03-15 14:55:56 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-15 16:55:16 -0700 |
commit | edf14cdbf9a0e5ab52698ca66d07a76ade0d5c46 (patch) | |
tree | 347fa732387b755a485c2d29e50485529e077b8d /mm | |
parent | 420adbe9fc1a45187cfa74df9dbfd72272c4e2fa (diff) | |
download | linux-edf14cdbf9a0e5ab52698ca66d07a76ade0d5c46.tar.bz2 |
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.c | 34 | ||||
-rw-r--r-- | mm/internal.h | 6 |
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 @@ #include <linux/memcontrol.h> #include <trace/events/mmflags.h> -static const struct trace_print_flags pageflag_names[] = { - __def_pageflag_names +#include "internal.h" + +const struct trace_print_flags pageflag_names[] = { + __def_pageflag_names, + {0, NULL} +}; + +const struct trace_print_flags gfpflag_names[] = { + __def_gfpflag_names, + {0, NULL} }; -static const struct trace_print_flags gfpflag_names[] = { - __def_gfpflag_names +const struct trace_print_flags vmaflag_names[] = { + __def_vmaflag_names, + {0, NULL} }; static void dump_flags(unsigned long flags, @@ -58,14 +67,15 @@ void dump_page_badflags(struct page *page, const char *reason, if (PageCompound(page)) pr_cont(" compound_mapcount: %d", compound_mapcount(page)); pr_cont("\n"); - BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS); - dump_flags(page->flags, pageflag_names, ARRAY_SIZE(pageflag_names)); + BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1); + dump_flags(page->flags, pageflag_names, + ARRAY_SIZE(pageflag_names) - 1); if (reason) pr_alert("page dumped because: %s\n", reason); if (page->flags & badflags) { pr_alert("bad because of flags:\n"); - dump_flags(page->flags & badflags, - pageflag_names, ARRAY_SIZE(pageflag_names)); + dump_flags(page->flags & badflags, pageflag_names, + ARRAY_SIZE(pageflag_names) - 1); } #ifdef CONFIG_MEMCG if (page->mem_cgroup) @@ -81,10 +91,6 @@ EXPORT_SYMBOL(dump_page); #ifdef CONFIG_DEBUG_VM -static const struct trace_print_flags vmaflag_names[] = { - __def_vmaflag_names -}; - void dump_vma(const struct vm_area_struct *vma) { pr_emerg("vma %p start %p end %p\n" @@ -96,7 +102,7 @@ void dump_vma(const struct vm_area_struct *vma) (unsigned long)pgprot_val(vma->vm_page_prot), vma->anon_vma, vma->vm_ops, vma->vm_pgoff, vma->vm_file, vma->vm_private_data); - dump_flags(vma->vm_flags, vmaflag_names, ARRAY_SIZE(vmaflag_names)); + dump_flags(vma->vm_flags, vmaflag_names, ARRAY_SIZE(vmaflag_names) - 1); } EXPORT_SYMBOL(dump_vma); @@ -168,7 +174,7 @@ void dump_mm(const struct mm_struct *mm) ); dump_flags(mm->def_flags, vmaflag_names, - ARRAY_SIZE(vmaflag_names)); + ARRAY_SIZE(vmaflag_names) - 1); } #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 @@ #include <linux/fs.h> #include <linux/mm.h> #include <linux/pagemap.h> +#include <linux/tracepoint-defs.h> /* * The set of flags that only affect watermark checking and reclaim @@ -466,4 +467,9 @@ static inline void try_to_unmap_flush_dirty(void) } #endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */ + +extern const struct trace_print_flags pageflag_names[]; +extern const struct trace_print_flags vmaflag_names[]; +extern const struct trace_print_flags gfpflag_names[]; + #endif /* __MM_INTERNAL_H */ |