diff options
Diffstat (limited to '')
-rw-r--r-- | patches/linux-3.3.0-vfs-dirty-inode.patch | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/patches/linux-3.3.0-vfs-dirty-inode.patch b/patches/linux-3.3.0-vfs-dirty-inode.patch new file mode 100644 index 0000000..4177093 --- /dev/null +++ b/patches/linux-3.3.0-vfs-dirty-inode.patch @@ -0,0 +1,103 @@ +From 9f7c5d04fdee46dbe715f2758152bb1664d4259c Mon Sep 17 00:00:00 2001 +From: Arjan van de Ven <arjan at linux.intel.com> +Date: Fri, 26 Nov 2010 12:18:03 -0800 +Subject: [PATCH 1/2] vfs: Add a trace point in the mark_inode_dirty function + +PowerTOP would like to be able to show who is keeping the disk +busy by dirtying data. The most logical spot for this is in the vfs +in the mark_inode_dirty() function, doing this on the block level +is not possible because by the time the IO hits the block layer the +guilty party can no longer be found ("kjournald" and "pdflush" are not +useful answers to "who caused this file to be dirty). + +The trace point follows the same logic/style as the block_dump code +and pretty much dumps the same data, just not to dmesg (and thus to +/var/log/messages) but via the trace events streams. + +Eventually we should be able to phase out the block dump code, but that's +for later on after a transition time. +--- + fs/fs-writeback.c | 3 +++ + include/linux/fs.h | 11 +++++++++++ + include/trace/events/writeback.h | 28 ++++++++++++++++++++++++++++ + 3 files changed, 42 insertions(+), 0 deletions(-) + +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index 5b4a936..5ef5bb0 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1081,6 +1081,9 @@ void __mark_inode_dirty(struct inode *inode, int flags) + if ((inode->i_state & flags) == flags) + return; + ++ if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)) ++ trace_writeback_inode_dirty(inode, flags); ++ + if (unlikely(block_dump)) + block_dump___mark_inode_dirty(inode); + +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 69cd5bb..e0ac37c 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1768,6 +1768,18 @@ struct super_operations { + + #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) + ++#define INODE_DIRTY_FLAGS \ ++ { I_DIRTY_SYNC, "DIRTY-SYNC" }, \ ++ { I_DIRTY_DATASYNC, "DIRTY-DATASYNC" }, \ ++ { I_DIRTY_PAGES, "DIRTY-PAGES" }, \ ++ { I_NEW, "NEW" }, \ ++ { I_WILL_FREE, "WILL-FREE" }, \ ++ { I_FREEING, "FREEING" }, \ ++ { I_CLEAR, "CLEAR" }, \ ++ { I_SYNC, "SYNC" }, \ ++ { I_REFERENCED, "REFERENCED" } ++ ++ + extern void __mark_inode_dirty(struct inode *, int); + static inline void mark_inode_dirty(struct inode *inode) + { +diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h +index 5973410..5f1e2a3 100644 +--- a/include/trace/events/writeback.h ++++ b/include/trace/events/writeback.h +@@ -408,6 +408,34 @@ DEFINE_EVENT(writeback_congest_waited_template, writeback_wait_iff_congested, + TP_ARGS(usec_timeout, usec_delayed) + ); + ++/* ++ * Tracepoint for dirtying an inode; used by PowerTOP ++ */ ++TRACE_EVENT(writeback_inode_dirty, ++ ++ TP_PROTO(struct inode *inode, int flags), ++ ++ TP_ARGS(inode, flags), ++ ++ TP_STRUCT__entry( ++ __field( __kernel_dev_t, dev ) ++ __field( ino_t, ino ) ++ __field( u32, flags ) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = inode->i_sb->s_dev; ++ __entry->ino = inode->i_ino; ++ __entry->flags = flags; ++ ), ++ ++ TP_printk("dev %d:%d ino %lu flags %d %s", MAJOR(__entry->dev), MINOR(__entry->dev), ++ (unsigned long) __entry->ino, ++ __entry->flags, ++ __print_flags(__entry->flags, "|", INODE_DIRTY_FLAGS) ++ ) ++); ++ + DECLARE_EVENT_CLASS(writeback_single_inode_template, + + TP_PROTO(struct inode *inode, +-- +1.7.8.5 + |