trace memory objects
Subsystems (7)
cover trace memory objects
Andrew, Ingo,
I'd like to introduce three memory object interfaces
/debug/tracing/objects/mm/pages/dump-pfn
/debug/tracing/objects/mm/pages/dump-file
/debug/tracing/objects/mm/pages/dump-fs
for dumping
- a range of PFNs
- the cached inodes (icache)
- the cached inode pages (page cache)
The "dump-pfn" interface is a superset of the existing /proc/kpageflags and /proc/kpagecount interfaces. Example output:
# echo 10000 +10 > /debug/tracing/objects/mm/pages/dump-pfn
# cat /debug/tracing/trace
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
zsh-3128 [000] 1393.460292: dump_page_frame: pfn=10001 page=ffffea000009c400 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460296: dump_page_frame: pfn=10002 page=ffffea000009c440 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460298: dump_page_frame: pfn=10003 page=ffffea000009c480 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460299: dump_page_frame: pfn=10004 page=ffffea000009c4c0 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460300: dump_page_frame: pfn=10005 page=ffffea000009c500 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460301: dump_page_frame: pfn=10006 page=ffffea000009c540 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460301: dump_page_frame: pfn=10007 page=ffffea000009c580 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460302: dump_page_frame: pfn=10008 page=ffffea000009c5c0 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460303: dump_page_frame: pfn=10009 page=ffffea000009c600 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reserved
zsh-3128 [000] 1393.460304: dump_page_frame: pfn=10010 page=ffffea000009c640 count=1 mapcount=0 memcg=0 private=0 mapping=0 index=0 flags=reservedThe "dump-file", "dump-fs" interfaces could be pretty useful for examining the page cache status. Example output:
# echo > /debug/tracing/trace
# echo / > /debug/tracing/objects/mm/pages/dump-fs
# head -50 /debug/tracing/trace
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
zsh-3128 [000] 1482.623149: dump_inode_cache: ino=1507329 size=4096 cached=4096 dirtied_when=4294676467 age=1482 state=____ type=DIR name=/
zsh-3128 [000] 1482.623157: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623340: dump_inode_cache: ino=1786836 size=12288 cached=12288 dirtied_when=4294676472 age=1482 state=____ type=DIR name=/sbin
zsh-3128 [000] 1482.623355: dump_page_cache: index=0 len=3 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623393: dump_inode_cache: ino=1786946 size=37312 cached=40960 dirtied_when=4294676473 age=1482 state=____ type=REG name=/sbin/init
zsh-3128 [000] 1482.623404: dump_page_cache: index=0 len=6 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 1482.623405: dump_page_cache: index=6 len=1 flags=M__A_U_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 1482.623406: dump_page_cache: index=7 len=1 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 1482.623408: dump_page_cache: index=8 len=2 flags=_____U_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623422: dump_inode_cache: ino=1507464 size=4 cached=4096 dirtied_when=4294676477 age=1482 state=____ type=LNK name=/lib64
zsh-3128 [000] 1482.623427: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623441: dump_inode_cache: ino=1590173 size=12288 cached=0 dirtied_when=4294676477 age=1482 state=____ type=DIR name=/lib
zsh-3128 [000] 1482.623458: dump_inode_cache: ino=1590265 size=27 cached=4096 dirtied_when=4294676478 age=1482 state=____ type=LNK name=/lib/ld-linux-x86-64.so.2
zsh-3128 [000] 1482.623462: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623478: dump_inode_cache: ino=1663440 size=4096 cached=0 dirtied_when=4294676479 age=1482 state=____ type=DIR name=/lib/x86_64-linux-gnu
zsh-3128 [000] 1482.623495: dump_inode_cache: ino=3293287 size=136936 cached=139264 dirtied_when=4294676480 age=1482 state=____ type=REG name=/lib/x86_64-linux-gnu/ld-2.13.so
zsh-3128 [000] 1482.623499: dump_page_cache: index=0 len=1 flags=M__ARU_____ count=28 mapcount=27 memcg=1
zsh-3128 [000] 1482.623501: dump_page_cache: index=1 len=3 flags=M__ARU_____ count=23 mapcount=22 memcg=1
zsh-3128 [000] 1482.623503: dump_page_cache: index=4 len=4 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623504: dump_page_cache: index=8 len=2 flags=M__ARU_____ count=34 mapcount=33 memcg=1
zsh-3128 [000] 1482.623506: dump_page_cache: index=10 len=3 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623508: dump_page_cache: index=13 len=1 flags=M__ARU_____ count=34 mapcount=33 memcg=1
zsh-3128 [000] 1482.623509: dump_page_cache: index=14 len=1 flags=M__ARU_____ count=33 mapcount=32 memcg=1
zsh-3128 [000] 1482.623510: dump_page_cache: index=15 len=1 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623511: dump_page_cache: index=16 len=1 flags=M__ARU_____ count=25 mapcount=24 memcg=1
zsh-3128 [000] 1482.623512: dump_page_cache: index=17 len=1 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623513: dump_page_cache: index=18 len=1 flags=M__ARU_____ count=10 mapcount=9 memcg=1
zsh-3128 [000] 1482.623514: dump_page_cache: index=19 len=1 flags=M__ARU_____ count=34 mapcount=33 memcg=1
zsh-3128 [000] 1482.623515: dump_page_cache: index=20 len=1 flags=M__ARU_____ count=23 mapcount=22 memcg=1
zsh-3128 [000] 1482.623516: dump_page_cache: index=21 len=1 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623517: dump_page_cache: index=22 len=1 flags=M__ARU_____ count=34 mapcount=33 memcg=1
zsh-3128 [000] 1482.623518: dump_page_cache: index=23 len=2 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623519: dump_page_cache: index=25 len=1 flags=M__ARU_____ count=33 mapcount=32 memcg=1
zsh-3128 [000] 1482.623520: dump_page_cache: index=26 len=1 flags=M__ARU_____ count=10 mapcount=9 memcg=1
zsh-3128 [000] 1482.623522: dump_page_cache: index=27 len=1 flags=M__ARU_____ count=4 mapcount=3 memcg=1
zsh-3128 [000] 1482.623523: dump_page_cache: index=28 len=1 flags=M__ARU_____ count=26 mapcount=25 memcg=1
zsh-3128 [000] 1482.623525: dump_page_cache: index=29 len=5 flags=_____U_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623540: dump_inode_cache: ino=1525477 size=12288 cached=0 dirtied_when=4294676489 age=1482 state=____ type=DIR name=/etc
zsh-3128 [000] 1482.623556: dump_inode_cache: ino=1526474 size=69589 cached=69632 dirtied_when=4294676491 age=1482 state=____ type=REG name=/etc/ld.so.cache
zsh-3128 [000] 1482.623561: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623562: dump_page_cache: index=1 len=1 flags=_____U_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623569: dump_page_cache: index=2 len=15 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623585: dump_inode_cache: ino=1590258 size=241632 cached=241664 dirtied_when=4294676493 age=1482 state=____ type=REG name=/lib/libsepol.so.1
zsh-3128 [000] 1482.623591: dump_page_cache: index=0 len=5 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 1482.623609: dump_page_cache: index=5 len=42 flags=_____U_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 1482.623610: dump_page_cache: index=47 len=1 flags=M__ARU_____ count=2 mapcount=1 memcg=1patches:
dump-pfn interface
(it looks more clean and easier for review to fold patches 1-5 into one, but let's keep the changelog for the initial post)
[RFC][PATCH 1/7] tracing/mm: add page frame snapshot trace [RFC][PATCH 2/7] tracing/mm: rename trigger file to dump-pfn [RFC][PATCH 3/7] tracing/mm: create trace_objects.c [RFC][PATCH 4/7] tracing/mm: dump more page frame information [RFC][PATCH 5/7] tracing/mm: accept echo-able input format for pfn range
dump-file and dump-fs interfaces
[RFC][PATCH 6/7] tracing/mm: add dump-file and dump-fs interfaces
add memcg support
[RFC][PATCH 7/7] tracing/mm: add memcg field
diffstat:
fs/inode.c | 8 fs/internal.h | 5 include/linux/fs.h | 1 include/linux/memcontrol.h | 6 include/linux/page-flags.h | 1 include/trace/events/mm.h | 170 ++++++++++++++ kernel/trace/Makefile | 2 kernel/trace/trace.h | 1 kernel/trace/trace_mm.c | 378 +++++++++++++++++++++++++++++++++ kernel/trace/trace_objects.c | 26 ++ mm/memcontrol.c | 18 + mm/page_alloc.c | 4 12 files changed, 612 insertions(+), 8 deletions(-)
Thanks,
Fengguang
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 1/7 tracing/mm: add page frame snapshot trace
From: Steven Rostedt <[email protected]>
This is a prototype to dump out a snapshot of the page tables to the tracing buffer. Currently it is very primitive, and just writes out the events. There is no synchronization to not loose the events, so /debug/tracing/buffer_size_kb has to be large enough for all events to fit.
We will do something about synchronization later. That is, have a way to read the buffer through the tracing/object/mm/page/X file and have the two in sync.
But this is just a prototype to get the ball rolling.
--- include/trace/events/mm.h | 48 ++++++++++ kernel/trace/Makefile | 1 kernel/trace/trace_mm.c | 172 ++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 include/trace/events/mm.h create mode 100644 kernel/trace/trace_mm.c
include/trace/events/mm.h new file +48 -0
@@ -0,0 +1,48 @@ +#if !defined(_TRACE_MM_H) || defined(TRACE_HEADER_MULTI_READ ) +#define _TRACE_MM_H + +#include <linux/tracepoint.h> +#include <linux/mm.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mm + +/** +* dump_pages - called by the trace page dump trigger +* @pfn: page frame number +* @page: pointer to the page frame +* +* This is a helper trace point into the dumping of the page frames. +* It will record various infromation about a page frame. +*/ +TRACE_EVENT (dump_pages, + + TP_PROTO(unsigned long pfn, struct page *page), + +TP_ARGS (pfn, page), + +TP_STRUCT__entry ( + __field( unsigned long, pfn ) + __field( unsigned long, flags ) + __field( unsigned long, index ) + __field( unsigned int, count ) + __field( unsigned int, mapcount ) + ), + +TP_fast_assign ( + __entry->pfn = pfn; + __entry->flags = page->flags; + __entry->count = atomic_read(&page->_count); + __entry->mapcount = page_mapcount(page); + __entry->index = page->index; + ), + +TP_printk ("pfn=%lu flags=%lx count=%u mapcount=%u index=%lu" , + __entry->pfn, __entry->flags, __entry->count, + __entry->mapcount, __entry->index) +); + +#endif /* _TRACE_MM_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h>
kernel/trace/Makefile +1 -0
@@ -53,6 +53,7 @@ endif obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o obj-$(CONFIG_TRACEPOINTS) += power-traces.o +obj-$(CONFIG_EVENT_TRACING) += trace_mm.o ifeq ($(CONFIG_TRACING),y) obj-$(CONFIG_KGDB_KDB) += trace_kdb.o endif
kernel/trace/trace_mm.c new file +172 -0
172 lines not on this page · raw message
RFC PATCH 1/7 tracing/mm: add page frame snapshot trace
In reply to Wu FengguangFrom: Steven Rostedt <[email protected]>
This is a prototype to dump out a snapshot of the page tables to the tracing buffer. Currently it is very primitive, and just writes out the events. There is no synchronization to not loose the events, so /debug/tracing/buffer_size_kb has to be large enough for all events to fit.
We will do something about synchronization later. That is, have a way to read the buffer through the tracing/object/mm/page/X file and have the two in sync.
But this is just a prototype to get the ball rolling.
--- include/trace/events/mm.h | 48 ++++++++++ kernel/trace/Makefile | 1 kernel/trace/trace_mm.c | 172 ++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 include/trace/events/mm.h create mode 100644 kernel/trace/trace_mm.c
include/trace/events/mm.h new file +48 -0
@@ -0,0 +1,48 @@ +#if !defined(_TRACE_MM_H) || defined(TRACE_HEADER_MULTI_READ ) +#define _TRACE_MM_H + +#include <linux/tracepoint.h> +#include <linux/mm.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mm + +/** +* dump_pages - called by the trace page dump trigger +* @pfn: page frame number +* @page: pointer to the page frame +* +* This is a helper trace point into the dumping of the page frames. +* It will record various infromation about a page frame. +*/ +TRACE_EVENT (dump_pages, + + TP_PROTO(unsigned long pfn, struct page *page), + +TP_ARGS (pfn, page), + +TP_STRUCT__entry ( + __field( unsigned long, pfn ) + __field( unsigned long, flags ) + __field( unsigned long, index ) + __field( unsigned int, count ) + __field( unsigned int, mapcount ) + ), + +TP_fast_assign ( + __entry->pfn = pfn; + __entry->flags = page->flags; + __entry->count = atomic_read(&page->_count); + __entry->mapcount = page_mapcount(page); + __entry->index = page->index; + ), + +TP_printk ("pfn=%lu flags=%lx count=%u mapcount=%u index=%lu" , + __entry->pfn, __entry->flags, __entry->count, + __entry->mapcount, __entry->index) +); + +#endif /* _TRACE_MM_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h>
kernel/trace/Makefile +1 -0
@@ -53,6 +53,7 @@ endif obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o obj-$(CONFIG_TRACEPOINTS) += power-traces.o +obj-$(CONFIG_EVENT_TRACING) += trace_mm.o ifeq ($(CONFIG_TRACING),y) obj-$(CONFIG_KGDB_KDB) += trace_kdb.o endif
kernel/trace/trace_mm.c new file +172 -0
172 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Joe Perches
maintainerPATCH 1/1 kernel.h/checkpatch: Mark strict_strto<foo> and simple_strto<foo> as obsolete
Mark obsolete/deprecated strict_strto<foo> and simple_strto<foo> functions and macros as obsolete.
Update checkpatch to warn about their use.
---
include/linux/kernel.h | 4 ++++ scripts/checkpatch.pl | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-)
include/linux/kernel.h +4 -0
@@ -287,6 +287,8 @@ static inline int __must_check kstrtos32_from_user(const char __user *s, size_treturn kstrtoint_from_user (s, count, base, res); } +/* Obsolete, do not use. Use kstrto<foo> instead */ +extern unsigned long simple_strtoul (const char *,char **,unsigned int );extern long simple_strtol (const char *,char **,unsigned int );extern unsigned long long simple_strtoull (const char *,char **,unsigned int );
@@ -296,6 +298,8 @@ extern long long simple_strtoll(const char *,char **,unsigned int);#define strict_strtoull kstrtoull#define strict_strtoll kstrtoll +/* lib/printf utilities */ +extern int sprintf (char * buf,const char * fmt, ...) __attribute__ ((format (printf,2 ,3 )));extern int vsprintf (char *buf,const char *,va_list )
scripts/checkpatch.pl +3 -3
@@ -3150,10 +3150,10 @@ sub process { "consider using a completion\n" . $herecurr); } -# recommend kstrto* over simple_strto* - if ($line =~ /\bsimple_(strto.*?)\s*\(/) { +# recommend kstrto* over simple_strto* and strict_strto* + if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { WARN("CONSIDER_KSTRTO", - "consider using kstrto* in preference to simple_$1\n" . $herecurr); + "$1 is obsolete, use k$3 instead\n" . $herecurr); } # check for __initcall(), use device_initcall() explicitly please if ($line =~ /^.\s*__initcall\s*\(/) {
RFC PATCH 2/7 tracing/mm: rename trigger file to dump-pfn
In reply to Wu FengguangFrom: Ingo Molnar <[email protected]>
Wu Fengguang noted that /debug/tracing/objects/mm/pages/trigger was not very intuitively named - rename it to 'dump-pfn', which covers its functionality better.
[ Impact: rename /debug/tracing file ]
--- include/trace/events/mm.h | 4 ++-- kernel/trace/trace_mm.c | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-)
kernel/trace/trace_mm.c +13 -13
@@ -15,8 +15,8 @@#define CREATE_TRACE_POINTS #include <trace/events/mm.h> -void trace_read_page_frames (unsigned long start,unsigned long end, -void (*trace)(unsigned long pfn,struct page *page)) +void trace_mm_page_frames (unsigned long start,unsigned long end, +void (*trace)(unsigned long pfn,struct page *page)) {unsigned long pfn = start;struct page *page;
@@ -37,22 +37,22 @@ void trace_read_page_frames(unsigned lon } } -static void trace_do_dump_pages (unsigned long pfn,struct page *page) +static void trace_mm_page_frame (unsigned long pfn,struct page *page) { -trace_dump_pages (pfn, page); +trace_dump_page_frame (pfn, page); }static ssize_t -trace_mm_trigger_read (struct file *filp,char __user *ubuf,size_t cnt, -loff_t *ppos) +trace_mm_pfn_range_read (struct file *filp,char __user *ubuf,size_t cnt, +loff_t *ppos) {return simple_read_from_buffer (ubuf, cnt, ppos,"0\n" ,2 ); }static ssize_t -trace_mm_trigger_write (struct file *filp,const char __user *ubuf,size_t cnt, -loff_t *ppos) +trace_mm_pfn_range_write (struct file *filp,const char __user *ubuf,size_t cnt, +loff_t *ppos) {unsigned long val, start, end;char buf[64 ];
@@ -67,7 +67,7 @@ trace_mm_trigger_write(struct file *filpif (tracing_update_buffers () <0 )return -ENOMEM ; -if (trace_set_clr_event ("mm" ,"dump_pages" ,1 )) +if (trace_set_clr_event ("mm" ,"dump_page_frame" ,1 ))return -EINVAL ; buf[cnt] =0 ;
@@ -82,7 +82,7 @@ trace_mm_trigger_write(struct file *filpelse end = start + val; -trace_read_page_frames (start, end, trace_do_dump_pages); +trace_mm_page_frames (start, end, trace_mm_page_frame); *ppos += cnt;
@@ -91,8 +91,8 @@ trace_mm_trigger_write(struct file *filpstatic const struct file_operations trace_mm_fops = { .open = tracing_open_generic, - .read = trace_mm_trigger_read, - .write = trace_mm_trigger_write, + .read = trace_mm_pfn_range_read, + .write = trace_mm_pfn_range_write, };/* move this into trace_objects.c when that file is created */
@@ -164,7 +164,7 @@ static __init int trace_objects_mm_init(if (!d_pages)return 0 ; -trace_create_file ("trigger" ,0600 , d_pages,NULL , +trace_create_file ("dump-pfn" ,0600 , d_pages,NULL , &trace_mm_fops);return 0 ;
include/trace/events/mm.h +2 -2
@@ -8,14 +8,14 @@#define TRACE_SYSTEM mm/** -* dump_pages - called by the trace page dump trigger +* dump_page_frame - called by the trace page dump trigger * @pfn: page frame number * @page: pointer to the page frame * * This is a helper trace point into the dumping of the page frames. * It will record various infromation about a page frame. */ -TRACE_EVENT(dump_pages, +TRACE_EVENT(dump_page_frame, TP_PROTO(unsigned long pfn, struct page *page),
RFC PATCH 2/7 tracing/mm: rename trigger file to dump-pfn
In reply to Wu FengguangFrom: Ingo Molnar <[email protected]>
Wu Fengguang noted that /debug/tracing/objects/mm/pages/trigger was not very intuitively named - rename it to 'dump-pfn', which covers its functionality better.
[ Impact: rename /debug/tracing file ]
--- include/trace/events/mm.h | 4 ++-- kernel/trace/trace_mm.c | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-)
kernel/trace/trace_mm.c +13 -13
@@ -15,8 +15,8 @@#define CREATE_TRACE_POINTS #include <trace/events/mm.h> -void trace_read_page_frames (unsigned long start,unsigned long end, -void (*trace)(unsigned long pfn,struct page *page)) +void trace_mm_page_frames (unsigned long start,unsigned long end, +void (*trace)(unsigned long pfn,struct page *page)) {unsigned long pfn = start;struct page *page;
@@ -37,22 +37,22 @@ void trace_read_page_frames(unsigned lon } } -static void trace_do_dump_pages (unsigned long pfn,struct page *page) +static void trace_mm_page_frame (unsigned long pfn,struct page *page) { -trace_dump_pages (pfn, page); +trace_dump_page_frame (pfn, page); }static ssize_t -trace_mm_trigger_read (struct file *filp,char __user *ubuf,size_t cnt, -loff_t *ppos) +trace_mm_pfn_range_read (struct file *filp,char __user *ubuf,size_t cnt, +loff_t *ppos) {return simple_read_from_buffer (ubuf, cnt, ppos,"0\n" ,2 ); }static ssize_t -trace_mm_trigger_write (struct file *filp,const char __user *ubuf,size_t cnt, -loff_t *ppos) +trace_mm_pfn_range_write (struct file *filp,const char __user *ubuf,size_t cnt, +loff_t *ppos) {unsigned long val, start, end;char buf[64 ];
@@ -67,7 +67,7 @@ trace_mm_trigger_write(struct file *filpif (tracing_update_buffers () <0 )return -ENOMEM ; -if (trace_set_clr_event ("mm" ,"dump_pages" ,1 )) +if (trace_set_clr_event ("mm" ,"dump_page_frame" ,1 ))return -EINVAL ; buf[cnt] =0 ;
@@ -82,7 +82,7 @@ trace_mm_trigger_write(struct file *filpelse end = start + val; -trace_read_page_frames (start, end, trace_do_dump_pages); +trace_mm_page_frames (start, end, trace_mm_page_frame); *ppos += cnt;
@@ -91,8 +91,8 @@ trace_mm_trigger_write(struct file *filpstatic const struct file_operations trace_mm_fops = { .open = tracing_open_generic, - .read = trace_mm_trigger_read, - .write = trace_mm_trigger_write, + .read = trace_mm_pfn_range_read, + .write = trace_mm_pfn_range_write, };/* move this into trace_objects.c when that file is created */
@@ -164,7 +164,7 @@ static __init int trace_objects_mm_init(if (!d_pages)return 0 ; -trace_create_file ("trigger" ,0600 , d_pages,NULL , +trace_create_file ("dump-pfn" ,0600 , d_pages,NULL , &trace_mm_fops);return 0 ;
include/trace/events/mm.h +2 -2
@@ -8,14 +8,14 @@#define TRACE_SYSTEM mm/** -* dump_pages - called by the trace page dump trigger +* dump_page_frame - called by the trace page dump trigger * @pfn: page frame number * @page: pointer to the page frame * * This is a helper trace point into the dumping of the page frames. * It will record various infromation about a page frame. */ -TRACE_EVENT(dump_pages, +TRACE_EVENT(dump_page_frame, TP_PROTO(unsigned long pfn, struct page *page),
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 3/7 tracing/mm: create trace_objects.c
In reply to Wu FengguangCode refactor: create trace_objects.c and move relevant code from trace_mm.c
--- kernel/trace/Makefile | 1 + kernel/trace/trace.h | 1 + kernel/trace/trace_mm.c | 22 ---------------------- kernel/trace/trace_objects.c | 26 ++++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 22 deletions(-)
kernel/trace/Makefile +1 -0
@@ -26,6 +26,7 @@ obj-$(CONFIG_RING_BUFFER) += ring_buffer obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o +obj-$(CONFIG_TRACING) += trace_objects.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o
kernel/trace/trace.h +1 -0
@@ -318,6 +318,7 @@ struct dentry *trace_create_file(const c const struct file_operations *fops);struct dentry *tracing_init_dentry (void ); +struct dentry *trace_objects_dir (void );struct ring_buffer_event ;
kernel/trace/trace_objects.c new file +26 -0
@@ -0,0 +1,26 @@ +#include <linux/debugfs.h> + +#include "trace.h" +#include "trace_output.h" + +struct dentry *trace_objects_dir (void ) +{ +static struct dentry *d_objects; +struct dentry *d_tracer; + +if (d_objects) +return d_objects; + + d_tracer =tracing_init_dentry (); +if (!d_tracer) +return NULL ; + + d_objects =debugfs_create_dir ("objects" , d_tracer); +if (!d_objects) +pr_warning ("Could not create debugfs " +"'objects' directory\n" ); + +return d_objects; +} + +
kernel/trace/trace_mm.c +0 -22
@@ -95,28 +95,6 @@ static const struct file_operations trac .write = trace_mm_pfn_range_write, }; -/* move this into trace_objects.c when that file is created */ -static struct dentry *trace_objects_dir (void ) -{ -static struct dentry *d_objects; -struct dentry *d_tracer; - -if (d_objects) -return d_objects; - - d_tracer =tracing_init_dentry (); -if (!d_tracer) -return NULL ; - - d_objects =debugfs_create_dir ("objects" , d_tracer); -if (!d_objects) -pr_warning ("Could not create debugfs " -"'objects' directory\n" ); - -return d_objects; -} - -static struct dentry *trace_objects_mm_dir (void ) {static struct dentry *d_mm;
RFC PATCH 3/7 tracing/mm: create trace_objects.c
In reply to Wu FengguangCode refactor: create trace_objects.c and move relevant code from trace_mm.c
--- kernel/trace/Makefile | 1 + kernel/trace/trace.h | 1 + kernel/trace/trace_mm.c | 22 ---------------------- kernel/trace/trace_objects.c | 26 ++++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 22 deletions(-)
kernel/trace/Makefile +1 -0
@@ -26,6 +26,7 @@ obj-$(CONFIG_RING_BUFFER) += ring_buffer obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o +obj-$(CONFIG_TRACING) += trace_objects.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o
kernel/trace/trace.h +1 -0
@@ -318,6 +318,7 @@ struct dentry *trace_create_file(const c const struct file_operations *fops);struct dentry *tracing_init_dentry (void ); +struct dentry *trace_objects_dir (void );struct ring_buffer_event ;
kernel/trace/trace_objects.c new file +26 -0
@@ -0,0 +1,26 @@ +#include <linux/debugfs.h> + +#include "trace.h" +#include "trace_output.h" + +struct dentry *trace_objects_dir (void ) +{ +static struct dentry *d_objects; +struct dentry *d_tracer; + +if (d_objects) +return d_objects; + + d_tracer =tracing_init_dentry (); +if (!d_tracer) +return NULL ; + + d_objects =debugfs_create_dir ("objects" , d_tracer); +if (!d_objects) +pr_warning ("Could not create debugfs " +"'objects' directory\n" ); + +return d_objects; +} + +
kernel/trace/trace_mm.c +0 -22
@@ -95,28 +95,6 @@ static const struct file_operations trac .write = trace_mm_pfn_range_write, }; -/* move this into trace_objects.c when that file is created */ -static struct dentry *trace_objects_dir (void ) -{ -static struct dentry *d_objects; -struct dentry *d_tracer; - -if (d_objects) -return d_objects; - - d_tracer =tracing_init_dentry (); -if (!d_tracer) -return NULL ; - - d_objects =debugfs_create_dir ("objects" , d_tracer); -if (!d_objects) -pr_warning ("Could not create debugfs " -"'objects' directory\n" ); - -return d_objects; -} - -static struct dentry *trace_objects_mm_dir (void ) {static struct dentry *d_mm;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 4/7 tracing/mm: dump more page frame information
In reply to Wu FengguangAdd 4 more fields to dump_page_frame trace event.
1) stable page flags in addition to the raw page flags
User space should only make use the stable page flags. The raw page flags is stored mainly to take advantage of ftrace_print_flags_seq() for showing symbolic flag names.
2) struct page address
3) page->private
4) page->mapping
The above 3 fields are mainly targeted for VM debug aids.
--- include/linux/page-flags.h | 1 + include/trace/events/mm.h | 29 +++++++++++++++++++++++++---- mm/page_alloc.c | 4 ++-- 3 files changed, 28 insertions(+), 6 deletions(-)
mm/page_alloc.c +2 -2
@@ -5743,7 +5743,7 @@ bool is_free_buddy_page(struct page *pag }#endif -static struct trace_print_flags pageflag_names[] = { +struct trace_print_flags pageflag_names[] = { {1UL << PG_locked,"locked" }, {1UL << PG_error,"error" }, {1UL << PG_referenced,"referenced" },
@@ -5790,7 +5790,7 @@ static void dump_page_flags(unsigned lonprintk (KERN_ALERT "page flags: %#lx(" , flags);/* remove zone id */ - flags &= (1UL <<NR_PAGEFLAGS ) -1 ; + flags &=PAGE_FLAGS_MASK ;for (i =0 ; pageflag_names[i].name && flags; i++) {
include/linux/page-flags.h +1 -0
@@ -462,6 +462,7 @@ static inline int PageTransCompound(stru* there has been a kernel bug or struct page corruption. */ #define PAGE_FLAGS_CHECK_AT_PREP ((1 << NR_PAGEFLAGS) - 1) +#define PAGE_FLAGS_MASK ((1 << NR_PAGEFLAGS) - 1)#define PAGE_FLAGS_PRIVATE \ (1 << PG_private | 1 << PG_private_2)
include/trace/events/mm.h +25 -4
@@ -2,11 +2,14 @@#define _TRACE_MM_H#include <linux/tracepoint.h> +#include <linux/page-flags.h> #include <linux/mm.h> #undef TRACE_SYSTEM#define TRACE_SYSTEM mm +extern struct trace_print_flags pageflag_names[]; +/** * dump_page_frame - called by the trace page dump trigger * @pfn: page frame number
@@ -23,23 +26,41 @@ TRACE_EVENT(dump_page_frame,TP_STRUCT__entry (__field (unsigned long ,pfn ) + __field( struct page *, page ) +__field ( u64, stable_flags ) __field( unsigned long, flags ) - __field( unsigned long, index ) __field( unsigned int, count ) __field( unsigned int, mapcount ) + __field( unsigned long, private ) + __field( unsigned long, mapping ) + __field( unsigned long, index ) ),TP_fast_assign ( __entry->pfn = pfn; + __entry->page = page; + __entry->stable_flags =stable_page_flags (page); __entry->flags = page->flags; __entry->count =atomic_read (&page->_count); __entry->mapcount =page_mapcount (page); + __entry->private = page->private; + __entry->mapping = (unsigned long )page->mapping; __entry->index = page->index; ), -TP_printk ("pfn=%lu flags=%lx count=%u mapcount=%u index=%lu" , - __entry->pfn, __entry->flags, __entry->count, - __entry->mapcount, __entry->index) +TP_printk ("pfn=%lu page=%p count=%u mapcount=%u " +"private=%lx mapping=%lx index=%lx flags=%s" , + __entry->pfn, + __entry->page, + __entry->count, + __entry->mapcount, + __entry->private, + __entry->mapping, + __entry->index, +ftrace_print_flags_seq (p,"|" , + __entry->flags &PAGE_FLAGS_MASK , + pageflag_names) + ) );#endif /* _TRACE_MM_H */
RFC PATCH 4/7 tracing/mm: dump more page frame information
In reply to Wu FengguangAdd 4 more fields to dump_page_frame trace event.
1) stable page flags in addition to the raw page flags
User space should only make use the stable page flags. The raw page flags is stored mainly to take advantage of ftrace_print_flags_seq() for showing symbolic flag names.
2) struct page address
3) page->private
4) page->mapping
The above 3 fields are mainly targeted for VM debug aids.
--- include/linux/page-flags.h | 1 + include/trace/events/mm.h | 29 +++++++++++++++++++++++++---- mm/page_alloc.c | 4 ++-- 3 files changed, 28 insertions(+), 6 deletions(-)
mm/page_alloc.c +2 -2
@@ -5743,7 +5743,7 @@ bool is_free_buddy_page(struct page *pag }#endif -static struct trace_print_flags pageflag_names[] = { +struct trace_print_flags pageflag_names[] = { {1UL << PG_locked,"locked" }, {1UL << PG_error,"error" }, {1UL << PG_referenced,"referenced" },
@@ -5790,7 +5790,7 @@ static void dump_page_flags(unsigned lonprintk (KERN_ALERT "page flags: %#lx(" , flags);/* remove zone id */ - flags &= (1UL <<NR_PAGEFLAGS ) -1 ; + flags &=PAGE_FLAGS_MASK ;for (i =0 ; pageflag_names[i].name && flags; i++) {
include/linux/page-flags.h +1 -0
@@ -462,6 +462,7 @@ static inline int PageTransCompound(stru* there has been a kernel bug or struct page corruption. */ #define PAGE_FLAGS_CHECK_AT_PREP ((1 << NR_PAGEFLAGS) - 1) +#define PAGE_FLAGS_MASK ((1 << NR_PAGEFLAGS) - 1)#define PAGE_FLAGS_PRIVATE \ (1 << PG_private | 1 << PG_private_2)
include/trace/events/mm.h +25 -4
@@ -2,11 +2,14 @@#define _TRACE_MM_H#include <linux/tracepoint.h> +#include <linux/page-flags.h> #include <linux/mm.h> #undef TRACE_SYSTEM#define TRACE_SYSTEM mm +extern struct trace_print_flags pageflag_names[]; +/** * dump_page_frame - called by the trace page dump trigger * @pfn: page frame number
@@ -23,23 +26,41 @@ TRACE_EVENT(dump_page_frame,TP_STRUCT__entry (__field (unsigned long ,pfn ) + __field( struct page *, page ) +__field ( u64, stable_flags ) __field( unsigned long, flags ) - __field( unsigned long, index ) __field( unsigned int, count ) __field( unsigned int, mapcount ) + __field( unsigned long, private ) + __field( unsigned long, mapping ) + __field( unsigned long, index ) ),TP_fast_assign ( __entry->pfn = pfn; + __entry->page = page; + __entry->stable_flags =stable_page_flags (page); __entry->flags = page->flags; __entry->count =atomic_read (&page->_count); __entry->mapcount =page_mapcount (page); + __entry->private = page->private; + __entry->mapping = (unsigned long )page->mapping; __entry->index = page->index; ), -TP_printk ("pfn=%lu flags=%lx count=%u mapcount=%u index=%lu" , - __entry->pfn, __entry->flags, __entry->count, - __entry->mapcount, __entry->index) +TP_printk ("pfn=%lu page=%p count=%u mapcount=%u " +"private=%lx mapping=%lx index=%lx flags=%s" , + __entry->pfn, + __entry->page, + __entry->count, + __entry->mapcount, + __entry->private, + __entry->mapping, + __entry->index, +ftrace_print_flags_seq (p,"|" , + __entry->flags &PAGE_FLAGS_MASK , + pageflag_names) + ) );#endif /* _TRACE_MM_H */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 5/7 tracing/mm: accept echo-able input format for pfn range
In reply to Wu FengguangThe seek+write style input for specifying pfn range is not scriptable. Change it to more user friendly echo-able format.
Before patch:
fd = open("/debug/tracing/object/mm/page/dump-pfn");
seek(fd, start);
write(fd, "size");After patch:
echo start +size > /debug/tracing/object/mm/page/dump-pfn
or
echo start end > /debug/tracing/object/mm/page/dump-pfn
--- kernel/trace/trace_mm.c | 39 +++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-)
kernel/trace/trace_mm.c +24 -15
@@ -9,6 +9,7 @@#include <linux/bootmem.h> #include <linux/debugfs.h> #include <linux/uaccess.h> +#include <linux/ctype.h> #include "trace_output.h"
@@ -24,8 +25,8 @@ void trace_mm_page_frames(unsigned longif (start > max_pfn -1 )return ; -if (end > max_pfn -1 ) - end = max_pfn -1 ; +if (end > max_pfn) + end = max_pfn;while (pfn < end) { page =NULL ;
@@ -50,13 +51,20 @@ trace_mm_pfn_range_read(struct file *fil } +/* +* recognized formats: +* "M N" start=M, end=N +* "M" start=M, end=M+1 +* "M +N" start=M, end=M+N-1 +*/ static ssize_t trace_mm_pfn_range_write (struct file *filp,const char __user *ubuf,size_t cnt,loff_t *ppos) { -unsigned long val, start, end; +unsigned long start; +unsigned long end =0 ;char buf[64 ]; -int ret; +char *ptr;if (cnt >=sizeof (buf))return -EINVAL ;
@@ -72,19 +80,20 @@ trace_mm_pfn_range_write(struct file *fi buf[cnt] =0 ; - ret =strict_strtol (buf,10 , &val); -if (ret <0 ) -return ret; - - start = *ppos; -if (val <0 ) - end = max_pfn -1 ; -else - end = start + val; + start =simple_strtoul (buf, &ptr,0 ); -trace_mm_page_frames (start, end, trace_mm_page_frame); +for (; *ptr; ptr++) { +if (isdigit (*ptr)) { +if (*(ptr -1 ) =='+' ) + end = start; + end +=simple_strtoul (ptr,NULL ,0 ); +break ; + } + } +if (!*ptr) + end = start +1 ; - *ppos += cnt; +trace_mm_page_frames (start, end, trace_mm_page_frame);return cnt; }
RFC PATCH 5/7 tracing/mm: accept echo-able input format for pfn range
In reply to Wu FengguangThe seek+write style input for specifying pfn range is not scriptable. Change it to more user friendly echo-able format.
Before patch:
fd = open("/debug/tracing/object/mm/page/dump-pfn");
seek(fd, start);
write(fd, "size");After patch:
echo start +size > /debug/tracing/object/mm/page/dump-pfn
or
echo start end > /debug/tracing/object/mm/page/dump-pfn
--- kernel/trace/trace_mm.c | 39 +++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-)
kernel/trace/trace_mm.c +24 -15
@@ -9,6 +9,7 @@#include <linux/bootmem.h> #include <linux/debugfs.h> #include <linux/uaccess.h> +#include <linux/ctype.h> #include "trace_output.h"
@@ -24,8 +25,8 @@ void trace_mm_page_frames(unsigned longif (start > max_pfn -1 )return ; -if (end > max_pfn -1 ) - end = max_pfn -1 ; +if (end > max_pfn) + end = max_pfn;while (pfn < end) { page =NULL ;
@@ -50,13 +51,20 @@ trace_mm_pfn_range_read(struct file *fil } +/* +* recognized formats: +* "M N" start=M, end=N +* "M" start=M, end=M+1 +* "M +N" start=M, end=M+N-1 +*/ static ssize_t trace_mm_pfn_range_write (struct file *filp,const char __user *ubuf,size_t cnt,loff_t *ppos) { -unsigned long val, start, end; +unsigned long start; +unsigned long end =0 ;char buf[64 ]; -int ret; +char *ptr;if (cnt >=sizeof (buf))return -EINVAL ;
@@ -72,19 +80,20 @@ trace_mm_pfn_range_write(struct file *fi buf[cnt] =0 ; - ret =strict_strtol (buf,10 , &val); -if (ret <0 ) -return ret; - - start = *ppos; -if (val <0 ) - end = max_pfn -1 ; -else - end = start + val; + start =simple_strtoul (buf, &ptr,0 ); -trace_mm_page_frames (start, end, trace_mm_page_frame); +for (; *ptr; ptr++) { +if (isdigit (*ptr)) { +if (*(ptr -1 ) =='+' ) + end = start; + end +=simple_strtoul (ptr,NULL ,0 ); +break ; + } + } +if (!*ptr) + end = start +1 ; - *ppos += cnt; +trace_mm_page_frames (start, end, trace_mm_page_frame);return cnt; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 6/7 tracing/mm: add dump-file and dump-fs interfaces
In reply to Wu FengguangThis dumps
- all cached files of a mounted fs (the inode-cache)
- all cached pages of a cached file (the page-cache)
Usage and Sample output:
# echo / > /debug/tracing/objects/mm/pages/dump-fs
# head -20 /debug/tracing/trace
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
zsh-3128 [000] 432.050943: dump_inode_cache: ino=1507329 size=4096 cached=4096 dirtied_when=4294676467 age=444 state=____ type=DIR name=/
zsh-3128 [000] 432.050949: dump_page_cache: index=0 len=1 flags=____RU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050962: dump_inode_cache: ino=1786836 size=12288 cached=12288 dirtied_when=4294676472 age=444 state=____ type=DIR name=/sbin
zsh-3128 [000] 432.050966: dump_page_cache: index=0 len=3 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050973: dump_inode_cache: ino=1786946 size=37312 cached=40960 dirtied_when=4294676473 age=444 state=____ type=REG name=/sbin/init
zsh-3128 [000] 432.050977: dump_page_cache: index=0 len=6 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 432.050978: dump_page_cache: index=6 len=1 flags=M__A_U_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 432.050978: dump_page_cache: index=7 len=1 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 432.050979: dump_page_cache: index=8 len=2 flags=_____U_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050986: dump_inode_cache: ino=1507464 size=4 cached=4096 dirtied_when=4294676477 age=444 state=____ type=LNK name=/lib64
zsh-3128 [000] 432.050989: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050995: dump_inode_cache: ino=1590173 size=12288 cached=0 dirtied_when=4294676477 age=444 state=____ type=DIR name=/lib
zsh-3128 [000] 432.051003: dump_inode_cache: ino=1590265 size=27 cached=4096 dirtied_when=4294676478 age=444 state=____ type=LNK name=/lib/ld-linux-x86-64.so.2
zsh-3128 [000] 432.051006: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.051013: dump_inode_cache: ino=1663440 size=4096 cached=0 dirtied_when=4294676479 age=444 state=____ type=DIR name=/lib/x86_64-linux-gnu
zsh-3128 [000] 432.051022: dump_inode_cache: ino=3293287 size=136936 cached=139264 dirtied_when=4294676480 age=444 state=____ type=REG name=/lib/x86_64-linux-gnu/ld-2.13.soHere "age" is the number of seconds from either inode create time, or last dirty time for dirtied inodes. "memcg" is the memory controller group id to be added by next patch.
--- fs/inode.c | 8 + fs/internal.h | 5 include/linux/fs.h | 1 include/trace/events/mm.h | 95 ++++++++++++++++ kernel/trace/trace_mm.c | 213 ++++++++++++++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 6 deletions(-)
include/trace/events/mm.h +95 -0
@@ -3,7 +3,10 @@#include <linux/tracepoint.h> #include <linux/page-flags.h> +#include <linux/memcontrol.h> +#include <linux/pagemap.h> #include <linux/mm.h> +#include <linux/kernel-page-flags.h> #undef TRACE_SYSTEM#define TRACE_SYSTEM mm
@@ -63,6 +66,98 @@ TRACE_EVENT(dump_page_frame, ) ); +TRACE_EVENT (dump_page_cache, + + TP_PROTO(struct page *page, unsigned long len), + +TP_ARGS (page, len), + +TP_STRUCT__entry ( + __field( unsigned long, index ) + __field( unsigned long, len ) + __field( u64, flags ) + __field( unsigned int, count ) + __field( unsigned int, mapcount ) + ), + +TP_fast_assign ( + __entry->index = page->index; + __entry->len = len; + __entry->flags = stable_page_flags(page); + __entry->count = atomic_read(&page->_count); + __entry->mapcount = page_mapcount(page); + ), + +TP_printk ("index=%lu len=%lu flags=%c%c%c%c%c%c%c%c%c%c%c " +"count=%u mapcount=%u" , + __entry->index, + __entry->len, + __entry->flags & (1ULL <<KPF_MMAP ) ?'M' :'_' , + __entry->flags & (1ULL <<KPF_MLOCKED ) ?'m' :'_' , + __entry->flags & (1ULL <<KPF_UNEVICTABLE ) ?'u' :'_' , + __entry->flags & (1ULL <<KPF_ACTIVE ) ?'A' :'_' , + __entry->flags & (1ULL <<KPF_REFERENCED ) ?'R' :'_' , + __entry->flags & (1ULL <<KPF_UPTODATE ) ?'U' :'_' , + __entry->flags & (1ULL <<KPF_DIRTY ) ?'D' :'_' , + __entry->flags & (1ULL <<KPF_WRITEBACK ) ?'W' :'_' , + __entry->flags & (1ULL <<KPF_RECLAIM ) ?'I' :'_' , + __entry->flags & (1ULL <<KPF_MAPPEDTODISK ) ?'d' :'_' , + __entry->flags & (1ULL <<KPF_PRIVATE ) ?'P' :'_' , + __entry->count, + __entry->mapcount) +); + + +#define show_inode_type (val) __print_symbolic(val, \ + { S_IFREG, "REG" }, \ + { S_IFDIR, "DIR" }, \ + { S_IFLNK, "LNK" }, \ + { S_IFBLK, "BLK" }, \ + { S_IFCHR, "CHR" }, \ + { S_IFIFO, "FIFO" }, \ + { S_IFSOCK, "SOCK" }) + +TRACE_EVENT (dump_inode_cache, + + TP_PROTO(struct inode *inode, char *name, int len), + +TP_ARGS (inode, name, len), + +TP_STRUCT__entry ( + __field( unsigned long, ino ) + __field( loff_t, size ) /* bytes */ + __field( loff_t, cached ) /* bytes */ + __field( unsigned long, dirtied_when ) + __field( unsigned long, state ) + __field( umode_t, mode ) +__dynamic_array (char, file, len ) + ), + +TP_fast_assign ( + __entry->ino = inode->i_ino; + __entry->size = i_size_read(inode); + __entry->cached = inode->i_mapping->nrpages << PAGE_CACHE_SHIFT; + __entry->dirtied_when = inode->dirtied_when; + __entry->state = inode->i_state; + __entry->mode = inode->i_mode; + memcpy(__get_str(file), name, len); + ), + +TP_printk ("ino=%lu size=%llu cached=%llu dirtied_when=%lu age=%lu " +"state=%c%c%c%c type=%s name=%s" , + __entry->ino, + __entry->size, + __entry->cached, + __entry->dirtied_when, + (jiffies - __entry->dirtied_when) /HZ , + __entry->state &I_DIRTY_PAGES ?'D' :'_' , + __entry->state &I_DIRTY_DATASYNC ?'d' :'_' , + __entry->state &I_DIRTY_SYNC ?'m' :'_' , + __entry->state &I_SYNC ?'S' :'_' , +show_inode_type (__entry->mode &S_IFMT ), +__get_str (file)) +); +#endif /* _TRACE_MM_H */ /* This part must be outside protection */
kernel/trace/trace_mm.c +213 -0
237 lines not on this page · raw message
fs/inode.c +7 -1
@@ -158,7 +158,13 @@ int inode_init_always(struct super_block inode->i_bdev =NULL ; inode->i_cdev =NULL ; inode->i_rdev =0 ; - inode->dirtied_when =0 ; + +/* +* This records inode load time. It will be invalidated once inode is +* dirtied, or jiffies wraps around. Despite the pitfalls it still +* provides useful information for some use cases like fastboot. +*/ + inode->dirtied_when = jiffies;if (security_inode_alloc (inode)) goto out;
fs/internal.h +0 -5
@@ -124,11 +124,6 @@ extern long do_handle_open(int mountdirf struct file_handle __user *ufh, int open_flag);/* -* inode.c -*/ -extern spinlock_t inode_sb_list_lock; - -/* * fs-writeback.c */ extern void inode_wb_list_del (struct inode *inode);
include/linux/fs.h +1 -0
@@ -1378,6 +1378,7 @@ extern int send_sigurg(struct fown_strucextern struct list_head super_blocks;extern spinlock_t sb_lock; +extern spinlock_t inode_sb_list_lock;struct super_block {struct list_head s_list;/* Keep this first */
RFC PATCH 6/7 tracing/mm: add dump-file and dump-fs interfaces
In reply to Wu FengguangThis dumps
- all cached files of a mounted fs (the inode-cache)
- all cached pages of a cached file (the page-cache)
Usage and Sample output:
# echo / > /debug/tracing/objects/mm/pages/dump-fs
# head -20 /debug/tracing/trace
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
zsh-3128 [000] 432.050943: dump_inode_cache: ino=1507329 size=4096 cached=4096 dirtied_when=4294676467 age=444 state=____ type=DIR name=/
zsh-3128 [000] 432.050949: dump_page_cache: index=0 len=1 flags=____RU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050962: dump_inode_cache: ino=1786836 size=12288 cached=12288 dirtied_when=4294676472 age=444 state=____ type=DIR name=/sbin
zsh-3128 [000] 432.050966: dump_page_cache: index=0 len=3 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050973: dump_inode_cache: ino=1786946 size=37312 cached=40960 dirtied_when=4294676473 age=444 state=____ type=REG name=/sbin/init
zsh-3128 [000] 432.050977: dump_page_cache: index=0 len=6 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 432.050978: dump_page_cache: index=6 len=1 flags=M__A_U_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 432.050978: dump_page_cache: index=7 len=1 flags=M__ARU_____ count=2 mapcount=1 memcg=1
zsh-3128 [000] 432.050979: dump_page_cache: index=8 len=2 flags=_____U_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050986: dump_inode_cache: ino=1507464 size=4 cached=4096 dirtied_when=4294676477 age=444 state=____ type=LNK name=/lib64
zsh-3128 [000] 432.050989: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.050995: dump_inode_cache: ino=1590173 size=12288 cached=0 dirtied_when=4294676477 age=444 state=____ type=DIR name=/lib
zsh-3128 [000] 432.051003: dump_inode_cache: ino=1590265 size=27 cached=4096 dirtied_when=4294676478 age=444 state=____ type=LNK name=/lib/ld-linux-x86-64.so.2
zsh-3128 [000] 432.051006: dump_page_cache: index=0 len=1 flags=___ARU_____ count=1 mapcount=0 memcg=1
zsh-3128 [000] 432.051013: dump_inode_cache: ino=1663440 size=4096 cached=0 dirtied_when=4294676479 age=444 state=____ type=DIR name=/lib/x86_64-linux-gnu
zsh-3128 [000] 432.051022: dump_inode_cache: ino=3293287 size=136936 cached=139264 dirtied_when=4294676480 age=444 state=____ type=REG name=/lib/x86_64-linux-gnu/ld-2.13.soHere "age" is the number of seconds from either inode create time, or last dirty time for dirtied inodes. "memcg" is the memory controller group id to be added by next patch.
--- fs/inode.c | 8 + fs/internal.h | 5 include/linux/fs.h | 1 include/trace/events/mm.h | 95 ++++++++++++++++ kernel/trace/trace_mm.c | 213 ++++++++++++++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 6 deletions(-)
include/trace/events/mm.h +95 -0
@@ -3,7 +3,10 @@#include <linux/tracepoint.h> #include <linux/page-flags.h> +#include <linux/memcontrol.h> +#include <linux/pagemap.h> #include <linux/mm.h> +#include <linux/kernel-page-flags.h> #undef TRACE_SYSTEM#define TRACE_SYSTEM mm
@@ -63,6 +66,98 @@ TRACE_EVENT(dump_page_frame, ) ); +TRACE_EVENT (dump_page_cache, + + TP_PROTO(struct page *page, unsigned long len), + +TP_ARGS (page, len), + +TP_STRUCT__entry ( + __field( unsigned long, index ) + __field( unsigned long, len ) + __field( u64, flags ) + __field( unsigned int, count ) + __field( unsigned int, mapcount ) + ), + +TP_fast_assign ( + __entry->index = page->index; + __entry->len = len; + __entry->flags = stable_page_flags(page); + __entry->count = atomic_read(&page->_count); + __entry->mapcount = page_mapcount(page); + ), + +TP_printk ("index=%lu len=%lu flags=%c%c%c%c%c%c%c%c%c%c%c " +"count=%u mapcount=%u" , + __entry->index, + __entry->len, + __entry->flags & (1ULL <<KPF_MMAP ) ?'M' :'_' , + __entry->flags & (1ULL <<KPF_MLOCKED ) ?'m' :'_' , + __entry->flags & (1ULL <<KPF_UNEVICTABLE ) ?'u' :'_' , + __entry->flags & (1ULL <<KPF_ACTIVE ) ?'A' :'_' , + __entry->flags & (1ULL <<KPF_REFERENCED ) ?'R' :'_' , + __entry->flags & (1ULL <<KPF_UPTODATE ) ?'U' :'_' , + __entry->flags & (1ULL <<KPF_DIRTY ) ?'D' :'_' , + __entry->flags & (1ULL <<KPF_WRITEBACK ) ?'W' :'_' , + __entry->flags & (1ULL <<KPF_RECLAIM ) ?'I' :'_' , + __entry->flags & (1ULL <<KPF_MAPPEDTODISK ) ?'d' :'_' , + __entry->flags & (1ULL <<KPF_PRIVATE ) ?'P' :'_' , + __entry->count, + __entry->mapcount) +); + + +#define show_inode_type (val) __print_symbolic(val, \ + { S_IFREG, "REG" }, \ + { S_IFDIR, "DIR" }, \ + { S_IFLNK, "LNK" }, \ + { S_IFBLK, "BLK" }, \ + { S_IFCHR, "CHR" }, \ + { S_IFIFO, "FIFO" }, \ + { S_IFSOCK, "SOCK" }) + +TRACE_EVENT (dump_inode_cache, + + TP_PROTO(struct inode *inode, char *name, int len), + +TP_ARGS (inode, name, len), + +TP_STRUCT__entry ( + __field( unsigned long, ino ) + __field( loff_t, size ) /* bytes */ + __field( loff_t, cached ) /* bytes */ + __field( unsigned long, dirtied_when ) + __field( unsigned long, state ) + __field( umode_t, mode ) +__dynamic_array (char, file, len ) + ), + +TP_fast_assign ( + __entry->ino = inode->i_ino; + __entry->size = i_size_read(inode); + __entry->cached = inode->i_mapping->nrpages << PAGE_CACHE_SHIFT; + __entry->dirtied_when = inode->dirtied_when; + __entry->state = inode->i_state; + __entry->mode = inode->i_mode; + memcpy(__get_str(file), name, len); + ), + +TP_printk ("ino=%lu size=%llu cached=%llu dirtied_when=%lu age=%lu " +"state=%c%c%c%c type=%s name=%s" , + __entry->ino, + __entry->size, + __entry->cached, + __entry->dirtied_when, + (jiffies - __entry->dirtied_when) /HZ , + __entry->state &I_DIRTY_PAGES ?'D' :'_' , + __entry->state &I_DIRTY_DATASYNC ?'d' :'_' , + __entry->state &I_DIRTY_SYNC ?'m' :'_' , + __entry->state &I_SYNC ?'S' :'_' , +show_inode_type (__entry->mode &S_IFMT ), +__get_str (file)) +); +#endif /* _TRACE_MM_H */ /* This part must be outside protection */
kernel/trace/trace_mm.c +213 -0
237 lines not on this page · raw message
fs/inode.c +7 -1
@@ -158,7 +158,13 @@ int inode_init_always(struct super_block inode->i_bdev =NULL ; inode->i_cdev =NULL ; inode->i_rdev =0 ; - inode->dirtied_when =0 ; + +/* +* This records inode load time. It will be invalidated once inode is +* dirtied, or jiffies wraps around. Despite the pitfalls it still +* provides useful information for some use cases like fastboot. +*/ + inode->dirtied_when = jiffies;if (security_inode_alloc (inode)) goto out;
fs/internal.h +0 -5
@@ -124,11 +124,6 @@ extern long do_handle_open(int mountdirf struct file_handle __user *ufh, int open_flag);/* -* inode.c -*/ -extern spinlock_t inode_sb_list_lock; - -/* * fs-writeback.c */ extern void inode_wb_list_del (struct inode *inode);
include/linux/fs.h +1 -0
@@ -1378,6 +1378,7 @@ extern int send_sigurg(struct fown_strucextern struct list_head super_blocks;extern spinlock_t sb_lock; +extern spinlock_t inode_sb_list_lock;struct super_block {struct list_head s_list;/* Keep this first */
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 7/7 tracing/mm: add memcg field
In reply to Wu FengguangDump the memcg id associated with a pagecache page.
The downside is, the page_memcg_id() is a pretty heavy weight function that needs to lock/unlock the page..
--- include/linux/memcontrol.h | 6 ++++++ include/trace/events/mm.h | 16 +++++++++++----- kernel/trace/trace_mm.c | 12 +++++++++--- mm/memcontrol.c | 18 ++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-)
include/linux/memcontrol.h +6 -0
@@ -91,6 +91,7 @@ extern void mem_cgroup_uncharge_cache_paextern void mem_cgroup_out_of_memory (struct mem_cgroup *memcg,gfp_t gfp_mask);int task_in_mem_cgroup (struct task_struct *task,const struct mem_cgroup *memcg); +extern unsigned short page_memcg_id (struct page *page);extern struct mem_cgroup *try_get_mem_cgroup_from_page (struct page *page);extern struct mem_cgroup *mem_cgroup_from_task (struct task_struct *p);extern struct mem_cgroup *try_get_mem_cgroup_from_mm (struct mm_struct *mm);
@@ -199,6 +200,11 @@ static inline int mem_cgroup_try_charge_return 0 ; } +static inline unsigned short page_memcg_id (struct page *page) +{ +return 0 ; +} +static inline void mem_cgroup_commit_charge_swapin (struct page *page,struct mem_cgroup *ptr) {
mm/memcontrol.c +18 -0
@@ -591,6 +591,24 @@ mem_cgroup_largest_soft_limit_node(strucreturn mz; } +unsigned short page_memcg_id (struct page *page) +{ +struct mem_cgroup *memcg; +struct cgroup_subsys_state *css; +unsigned short id =0 ; + +lock_page (page); + memcg =try_get_mem_cgroup_from_page (page); +if (memcg) { + css =mem_cgroup_css (memcg); + id =css_id (css); +css_put (css); + } +unlock_page (page); + +return id; +} +/* * Implementation Note: reading percpu statistics for memcg. *
include/trace/events/mm.h +11 -5
@@ -34,6 +34,7 @@ TRACE_EVENT(dump_page_frame, __field( unsigned long, flags ) __field( unsigned int, count ) __field( unsigned int, mapcount ) + __field( unsigned int, memcg ) __field( unsigned long, private ) __field( unsigned long, mapping ) __field( unsigned long, index )
@@ -46,17 +47,19 @@ TRACE_EVENT(dump_page_frame, __entry->flags = page->flags; __entry->count =atomic_read (&page->_count); __entry->mapcount =page_mapcount (page); + __entry->memcg =page_memcg_id (page); __entry->private = page->private; __entry->mapping = (unsigned long )page->mapping; __entry->index = page->index; ), TP_printk("pfn=%lu page=%p count=%u mapcount=%u " - "private=%lx mapping=%lx index=%lx flags=%s", + "memcg=%u private=%lx mapping=%lx index=%lx flags=%s", __entry->pfn, __entry->page, __entry->count, __entry->mapcount, + __entry->memcg, __entry->private, __entry->mapping, __entry->index,
@@ -68,9 +71,9 @@ TRACE_EVENT(dump_page_frame, TRACE_EVENT(dump_page_cache, - TP_PROTO(struct page *page, unsigned long len), + TP_PROTO(struct page *page, unsigned long len, unsigned int memcg), - TP_ARGS(page, len), + TP_ARGS(page, len, memcg), TP_STRUCT__entry( __field( unsigned long, index )
@@ -78,6 +81,7 @@ TRACE_EVENT(dump_page_cache, __field( u64, flags ) __field( unsigned int, count ) __field( unsigned int, mapcount ) + __field( unsigned int, memcg ) ), TP_fast_assign(
@@ -86,10 +90,11 @@ TRACE_EVENT(dump_page_cache, __entry->flags =stable_page_flags (page); __entry->count =atomic_read (&page->_count); __entry->mapcount =page_mapcount (page); + __entry->memcg = memcg; ), TP_printk("index=%lu len=%lu flags=%c%c%c%c%c%c%c%c%c%c%c " - "count=%u mapcount=%u", + "count=%u mapcount=%u memcg=%u", __entry->index, __entry->len, __entry->flags & (1ULL << KPF_MMAP) ? 'M' : '_',
@@ -104,7 +109,8 @@ TRACE_EVENT(dump_page_cache, __entry->flags & (1ULL <<KPF_MAPPEDTODISK ) ?'d' :'_' , __entry->flags & (1ULL <<KPF_PRIVATE ) ?'P' :'_' , __entry->count, - __entry->mapcount) + __entry->mapcount, + __entry->memcg) );
kernel/trace/trace_mm.c +9 -3
@@ -155,6 +155,8 @@ static void dump_pagecache(struct addresstruct page *page;unsigned long start =0 ;unsigned long len =0 ; +unsigned int memcg0; +unsigned int memcg;int i;for (;;) {
@@ -165,23 +167,27 @@ static void dump_pagecache(struct addresif (nr_pages ==0 ) {if (len) -trace_dump_page_cache (page0, len); +trace_dump_page_cache (page0, len, memcg0);return ; }for (i =0 ; i < nr_pages; i++) { page = pages[i]; + memcg =page_memcg_id (page);if (len && page->index == start + len && -pages_similar (page0, page)) +pages_similar (page0, page) && + memcg0 == memcg) len++;else {if (len) -trace_dump_page_cache (page0, len); +trace_dump_page_cache (page0, len, + memcg0); page0 = page; start = page->index; len =1 ; + memcg0 = memcg; } }cond_resched ();
RFC PATCH 7/7 tracing/mm: add memcg field
In reply to Wu FengguangDump the memcg id associated with a pagecache page.
The downside is, the page_memcg_id() is a pretty heavy weight function that needs to lock/unlock the page..
--- include/linux/memcontrol.h | 6 ++++++ include/trace/events/mm.h | 16 +++++++++++----- kernel/trace/trace_mm.c | 12 +++++++++--- mm/memcontrol.c | 18 ++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-)
include/linux/memcontrol.h +6 -0
@@ -91,6 +91,7 @@ extern void mem_cgroup_uncharge_cache_paextern void mem_cgroup_out_of_memory (struct mem_cgroup *memcg,gfp_t gfp_mask);int task_in_mem_cgroup (struct task_struct *task,const struct mem_cgroup *memcg); +extern unsigned short page_memcg_id (struct page *page);extern struct mem_cgroup *try_get_mem_cgroup_from_page (struct page *page);extern struct mem_cgroup *mem_cgroup_from_task (struct task_struct *p);extern struct mem_cgroup *try_get_mem_cgroup_from_mm (struct mm_struct *mm);
@@ -199,6 +200,11 @@ static inline int mem_cgroup_try_charge_return 0 ; } +static inline unsigned short page_memcg_id (struct page *page) +{ +return 0 ; +} +static inline void mem_cgroup_commit_charge_swapin (struct page *page,struct mem_cgroup *ptr) {
mm/memcontrol.c +18 -0
@@ -591,6 +591,24 @@ mem_cgroup_largest_soft_limit_node(strucreturn mz; } +unsigned short page_memcg_id (struct page *page) +{ +struct mem_cgroup *memcg; +struct cgroup_subsys_state *css; +unsigned short id =0 ; + +lock_page (page); + memcg =try_get_mem_cgroup_from_page (page); +if (memcg) { + css =mem_cgroup_css (memcg); + id =css_id (css); +css_put (css); + } +unlock_page (page); + +return id; +} +/* * Implementation Note: reading percpu statistics for memcg. *
include/trace/events/mm.h +11 -5
@@ -34,6 +34,7 @@ TRACE_EVENT(dump_page_frame, __field( unsigned long, flags ) __field( unsigned int, count ) __field( unsigned int, mapcount ) + __field( unsigned int, memcg ) __field( unsigned long, private ) __field( unsigned long, mapping ) __field( unsigned long, index )
@@ -46,17 +47,19 @@ TRACE_EVENT(dump_page_frame, __entry->flags = page->flags; __entry->count =atomic_read (&page->_count); __entry->mapcount =page_mapcount (page); + __entry->memcg =page_memcg_id (page); __entry->private = page->private; __entry->mapping = (unsigned long )page->mapping; __entry->index = page->index; ), TP_printk("pfn=%lu page=%p count=%u mapcount=%u " - "private=%lx mapping=%lx index=%lx flags=%s", + "memcg=%u private=%lx mapping=%lx index=%lx flags=%s", __entry->pfn, __entry->page, __entry->count, __entry->mapcount, + __entry->memcg, __entry->private, __entry->mapping, __entry->index,
@@ -68,9 +71,9 @@ TRACE_EVENT(dump_page_frame, TRACE_EVENT(dump_page_cache, - TP_PROTO(struct page *page, unsigned long len), + TP_PROTO(struct page *page, unsigned long len, unsigned int memcg), - TP_ARGS(page, len), + TP_ARGS(page, len, memcg), TP_STRUCT__entry( __field( unsigned long, index )
@@ -78,6 +81,7 @@ TRACE_EVENT(dump_page_cache, __field( u64, flags ) __field( unsigned int, count ) __field( unsigned int, mapcount ) + __field( unsigned int, memcg ) ), TP_fast_assign(
@@ -86,10 +90,11 @@ TRACE_EVENT(dump_page_cache, __entry->flags =stable_page_flags (page); __entry->count =atomic_read (&page->_count); __entry->mapcount =page_mapcount (page); + __entry->memcg = memcg; ), TP_printk("index=%lu len=%lu flags=%c%c%c%c%c%c%c%c%c%c%c " - "count=%u mapcount=%u", + "count=%u mapcount=%u memcg=%u", __entry->index, __entry->len, __entry->flags & (1ULL << KPF_MMAP) ? 'M' : '_',
@@ -104,7 +109,8 @@ TRACE_EVENT(dump_page_cache, __entry->flags & (1ULL <<KPF_MAPPEDTODISK ) ?'d' :'_' , __entry->flags & (1ULL <<KPF_PRIVATE ) ?'P' :'_' , __entry->count, - __entry->mapcount) + __entry->mapcount, + __entry->memcg) );
kernel/trace/trace_mm.c +9 -3
@@ -155,6 +155,8 @@ static void dump_pagecache(struct addresstruct page *page;unsigned long start =0 ;unsigned long len =0 ; +unsigned int memcg0; +unsigned int memcg;int i;for (;;) {
@@ -165,23 +167,27 @@ static void dump_pagecache(struct addresif (nr_pages ==0 ) {if (len) -trace_dump_page_cache (page0, len); +trace_dump_page_cache (page0, len, memcg0);return ; }for (i =0 ; i < nr_pages; i++) { page = pages[i]; + memcg =page_memcg_id (page);if (len && page->index == start + len && -pages_similar (page0, page)) +pages_similar (page0, page) && + memcg0 == memcg) len++;else {if (len) -trace_dump_page_cache (page0, len); +trace_dump_page_cache (page0, len, + memcg0); page0 = page; start = page->index; len =1 ; + memcg0 = memcg; } }cond_resched ();
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 9 lines
dump-pfn interface
(it looks more clean and easier for review to fold patches 1-5 into one, but let's keep the changelog for the initial post)[RFC][PATCH 1/7] tracing/mm: add page frame snapshot trace [RFC][PATCH 2/7] tracing/mm: rename trigger file to dump-pfn [RFC][PATCH 3/7] tracing/mm: create
trace_objects.c[RFC][PATCH 4/7] tracing/mm: dump more page frame information [RFC][PATCH 5/7] tracing/mm: accept echo-able input format for pfn range
For your convenience, here is the combined diff for the above 5 incremental ones.
include/trace/events/mm.h new file +69 -0
@@ -0,0 +1,69 @@ +#if !defined(_TRACE_MM_H) || defined(TRACE_HEADER_MULTI_READ ) +#define _TRACE_MM_H + +#include <linux/tracepoint.h> +#include <linux/page-flags.h> +#include <linux/mm.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mm + +extern struct trace_print_flags pageflag_names[]; + +/** +* dump_page_frame - called by the trace page dump trigger +* @pfn: page frame number +* @page: pointer to the page frame +* +* This is a helper trace point into the dumping of the page frames. +* It will record various infromation about a page frame. +*/ +TRACE_EVENT (dump_page_frame, + + TP_PROTO(unsigned long pfn, struct page *page), + +TP_ARGS (pfn, page), + +TP_STRUCT__entry ( + __field( unsigned long, pfn ) + __field( struct page *, page ) + __field( u64, stable_flags ) + __field( unsigned long, flags ) + __field( unsigned int, count ) + __field( unsigned int, mapcount ) + __field( unsigned long, private ) + __field( unsigned long, mapping ) + __field( unsigned long, index ) + ), + +TP_fast_assign ( + __entry->pfn = pfn; + __entry->page = page; + __entry->stable_flags = stable_page_flags(page); + __entry->flags = page->flags; + __entry->count = atomic_read(&page->_count); + __entry->mapcount = page_mapcount(page); + __entry->private = page->private; + __entry->mapping = (unsigned long)page->mapping; + __entry->index = page->index; + ), + +TP_printk ("pfn=%lu page=%p count=%u mapcount=%u " +"private=%lx mapping=%lx index=%lx flags=%s" , + __entry->pfn, + __entry->page, + __entry->count, + __entry->mapcount, + __entry->private, + __entry->mapping, + __entry->index, +ftrace_print_flags_seq (p,"|" , + __entry->flags &PAGE_FLAGS_MASK , + pageflag_names) + ) +); + +#endif /* _TRACE_MM_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h>
kernel/trace/Makefile +2 -0
@@ -26,6 +26,7 @@ obj-$(CONFIG_RING_BUFFER) += ring_buffer obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o obj-$(CONFIG_TRACING) += trace.o +obj-$(CONFIG_TRACING) += trace_objects.o obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o
@@ -53,6 +54,7 @@ endif obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o obj-$(CONFIG_TRACEPOINTS) += power-traces.o +obj-$(CONFIG_EVENT_TRACING) += trace_mm.o ifeq ($(CONFIG_TRACING),y) obj-$(CONFIG_KGDB_KDB) += trace_kdb.o endif
kernel/trace/trace_mm.c new file +150 -0
150 lines not on this page · raw message
kernel/trace/trace.h +1 -0
@@ -318,6 +318,7 @@ struct dentry *trace_create_file(const c const struct file_operations *fops);struct dentry *tracing_init_dentry (void ); +struct dentry *trace_objects_dir (void );struct ring_buffer_event ;
kernel/trace/trace_objects.c new file +26 -0
@@ -0,0 +1,26 @@ +#include <linux/debugfs.h> + +#include "trace.h" +#include "trace_output.h" + +struct dentry *trace_objects_dir (void ) +{ +static struct dentry *d_objects; +struct dentry *d_tracer; + +if (d_objects) +return d_objects; + + d_tracer =tracing_init_dentry (); +if (!d_tracer) +return NULL ; + + d_objects =debugfs_create_dir ("objects" , d_tracer); +if (!d_objects) +pr_warning ("Could not create debugfs " +"'objects' directory\n" ); + +return d_objects; +} + +
mm/page_alloc.c +2 -2
@@ -5743,7 +5743,7 @@ bool is_free_buddy_page(struct page *pag }#endif -static struct trace_print_flags pageflag_names[] = { +struct trace_print_flags pageflag_names[] = { {1UL << PG_locked,"locked" }, {1UL << PG_error,"error" }, {1UL << PG_referenced,"referenced" },
@@ -5790,7 +5790,7 @@ static void dump_page_flags(unsigned lonprintk (KERN_ALERT "page flags: %#lx(" , flags);/* remove zone id */ - flags &= (1UL <<NR_PAGEFLAGS ) -1 ; + flags &=PAGE_FLAGS_MASK ;for (i =0 ; pageflag_names[i].name && flags; i++) {
include/linux/page-flags.h +1 -0
@@ -462,6 +462,7 @@ static inline int PageTransCompound(stru* there has been a kernel bug or struct page corruption. */ #define PAGE_FLAGS_CHECK_AT_PREP ((1 << NR_PAGEFLAGS) - 1) +#define PAGE_FLAGS_MASK ((1 << NR_PAGEFLAGS) - 1)#define PAGE_FLAGS_PRIVATE \ (1 << PG_private | 1 << PG_private_2)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>