Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm: trace filemap add and del

Use the events API to trace filemap loading and unloading of file pieces
into the page cache.

This patch aims at tracing the eviction reload cycle of executable and
shared libraries pages in a memory constrained environment.

The typical usage is to spot a specific device and inode (for example
/lib/libc.so) to see the eviction cycles, and find out if frequently
used code is rather spread across many pages (bad) or coallesced (good).

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Robert Jarzmik and committed by
Linus Torvalds
fe0bfaaf e3986295

+63
+58
include/trace/events/filemap.h
··· 1 + #undef TRACE_SYSTEM 2 + #define TRACE_SYSTEM filemap 3 + 4 + #if !defined(_TRACE_FILEMAP_H) || defined(TRACE_HEADER_MULTI_READ) 5 + #define _TRACE_FILEMAP_H 6 + 7 + #include <linux/types.h> 8 + #include <linux/tracepoint.h> 9 + #include <linux/mm.h> 10 + #include <linux/memcontrol.h> 11 + #include <linux/device.h> 12 + #include <linux/kdev_t.h> 13 + 14 + DECLARE_EVENT_CLASS(mm_filemap_op_page_cache, 15 + 16 + TP_PROTO(struct page *page), 17 + 18 + TP_ARGS(page), 19 + 20 + TP_STRUCT__entry( 21 + __field(struct page *, page) 22 + __field(unsigned long, i_ino) 23 + __field(unsigned long, index) 24 + __field(dev_t, s_dev) 25 + ), 26 + 27 + TP_fast_assign( 28 + __entry->page = page; 29 + __entry->i_ino = page->mapping->host->i_ino; 30 + __entry->index = page->index; 31 + if (page->mapping->host->i_sb) 32 + __entry->s_dev = page->mapping->host->i_sb->s_dev; 33 + else 34 + __entry->s_dev = page->mapping->host->i_rdev; 35 + ), 36 + 37 + TP_printk("dev %d:%d ino %lx page=%p pfn=%lu ofs=%lu", 38 + MAJOR(__entry->s_dev), MINOR(__entry->s_dev), 39 + __entry->i_ino, 40 + __entry->page, 41 + page_to_pfn(__entry->page), 42 + __entry->index << PAGE_SHIFT) 43 + ); 44 + 45 + DEFINE_EVENT(mm_filemap_op_page_cache, mm_filemap_delete_from_page_cache, 46 + TP_PROTO(struct page *page), 47 + TP_ARGS(page) 48 + ); 49 + 50 + DEFINE_EVENT(mm_filemap_op_page_cache, mm_filemap_add_to_page_cache, 51 + TP_PROTO(struct page *page), 52 + TP_ARGS(page) 53 + ); 54 + 55 + #endif /* _TRACE_FILEMAP_H */ 56 + 57 + /* This part must be outside protection */ 58 + #include <trace/define_trace.h>
+5
mm/filemap.c
··· 35 35 #include <linux/cleancache.h> 36 36 #include "internal.h" 37 37 38 + #define CREATE_TRACE_POINTS 39 + #include <trace/events/filemap.h> 40 + 38 41 /* 39 42 * FIXME: remove all knowledge of the buffer layer from the core VM 40 43 */ ··· 116 113 { 117 114 struct address_space *mapping = page->mapping; 118 115 116 + trace_mm_filemap_delete_from_page_cache(page); 119 117 /* 120 118 * if we're uptodate, flush out into the cleancache, otherwise 121 119 * invalidate any existing cleancache entries. We can't leave ··· 468 464 mapping->nrpages++; 469 465 __inc_zone_page_state(page, NR_FILE_PAGES); 470 466 spin_unlock_irq(&mapping->tree_lock); 467 + trace_mm_filemap_add_to_page_cache(page); 471 468 } else { 472 469 page->mapping = NULL; 473 470 /* Leave page->index set: truncation relies upon it */