diff options
| author | Curt Wohlgemuth <curtw@google.com> | 2011-10-07 23:54:10 -0400 |
|---|---|---|
| committer | Wu Fengguang <fengguang.wu@intel.com> | 2011-10-30 12:33:36 -0400 |
| commit | 0e175a1835ffc979e55787774e58ec79e41957d7 (patch) | |
| tree | 6ec4b65a8de4e9d1c12d26a1079079ed81d79450 /include | |
| parent | ad4e38dd6a33bb3a4882c487d7abe621e583b982 (diff) | |
writeback: Add a 'reason' to wb_writeback_work
This creates a new 'reason' field in a wb_writeback_work
structure, which unambiguously identifies who initiates
writeback activity. A 'wb_reason' enumeration has been
added to writeback.h, to enumerate the possible reasons.
The 'writeback_work_class' and tracepoint event class and
'writeback_queue_io' tracepoints are updated to include the
symbolic 'reason' in all trace events.
And the 'writeback_inodes_sbXXX' family of routines has had
a wb_stats parameter added to them, so callers can specify
why writeback is being started.
Acked-by: Jan Kara <jack@suse.cz>
Signed-off-by: Curt Wohlgemuth <curtw@google.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/backing-dev.h | 3 | ||||
| -rw-r--r-- | include/linux/writeback.h | 32 | ||||
| -rw-r--r-- | include/trace/events/writeback.h | 14 |
3 files changed, 38 insertions, 11 deletions
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index c3b92010d894..b1038bd686ac 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
| @@ -118,7 +118,8 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent, | |||
| 118 | int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); | 118 | int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); |
| 119 | void bdi_unregister(struct backing_dev_info *bdi); | 119 | void bdi_unregister(struct backing_dev_info *bdi); |
| 120 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); | 120 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); |
| 121 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages); | 121 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, |
| 122 | enum wb_reason reason); | ||
| 122 | void bdi_start_background_writeback(struct backing_dev_info *bdi); | 123 | void bdi_start_background_writeback(struct backing_dev_info *bdi); |
| 123 | int bdi_writeback_thread(void *data); | 124 | int bdi_writeback_thread(void *data); |
| 124 | int bdi_has_dirty_io(struct backing_dev_info *bdi); | 125 | int bdi_has_dirty_io(struct backing_dev_info *bdi); |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index ddb4652cb337..a378c295851f 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
| @@ -39,6 +39,23 @@ enum writeback_sync_modes { | |||
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | /* | 41 | /* |
| 42 | * why some writeback work was initiated | ||
| 43 | */ | ||
| 44 | enum wb_reason { | ||
| 45 | WB_REASON_BACKGROUND, | ||
| 46 | WB_REASON_TRY_TO_FREE_PAGES, | ||
| 47 | WB_REASON_SYNC, | ||
| 48 | WB_REASON_PERIODIC, | ||
| 49 | WB_REASON_LAPTOP_TIMER, | ||
| 50 | WB_REASON_FREE_MORE_MEM, | ||
| 51 | WB_REASON_FS_FREE_SPACE, | ||
| 52 | WB_REASON_FORKER_THREAD, | ||
| 53 | |||
| 54 | WB_REASON_MAX, | ||
| 55 | }; | ||
| 56 | extern const char *wb_reason_name[]; | ||
| 57 | |||
| 58 | /* | ||
| 42 | * A control structure which tells the writeback code what to do. These are | 59 | * A control structure which tells the writeback code what to do. These are |
| 43 | * always on the stack, and hence need no locking. They are always initialised | 60 | * always on the stack, and hence need no locking. They are always initialised |
| 44 | * in a manner such that unspecified fields are set to zero. | 61 | * in a manner such that unspecified fields are set to zero. |
| @@ -69,14 +86,17 @@ struct writeback_control { | |||
| 69 | */ | 86 | */ |
| 70 | struct bdi_writeback; | 87 | struct bdi_writeback; |
| 71 | int inode_wait(void *); | 88 | int inode_wait(void *); |
| 72 | void writeback_inodes_sb(struct super_block *); | 89 | void writeback_inodes_sb(struct super_block *, enum wb_reason reason); |
| 73 | void writeback_inodes_sb_nr(struct super_block *, unsigned long nr); | 90 | void writeback_inodes_sb_nr(struct super_block *, unsigned long nr, |
| 74 | int writeback_inodes_sb_if_idle(struct super_block *); | 91 | enum wb_reason reason); |
| 75 | int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr); | 92 | int writeback_inodes_sb_if_idle(struct super_block *, enum wb_reason reason); |
| 93 | int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr, | ||
| 94 | enum wb_reason reason); | ||
| 76 | void sync_inodes_sb(struct super_block *); | 95 | void sync_inodes_sb(struct super_block *); |
| 77 | long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages); | 96 | long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, |
| 97 | enum wb_reason reason); | ||
| 78 | long wb_do_writeback(struct bdi_writeback *wb, int force_wait); | 98 | long wb_do_writeback(struct bdi_writeback *wb, int force_wait); |
| 79 | void wakeup_flusher_threads(long nr_pages); | 99 | void wakeup_flusher_threads(long nr_pages, enum wb_reason reason); |
| 80 | 100 | ||
| 81 | /* writeback.h requires fs.h; it, too, is not included from here. */ | 101 | /* writeback.h requires fs.h; it, too, is not included from here. */ |
| 82 | static inline void wait_on_inode(struct inode *inode) | 102 | static inline void wait_on_inode(struct inode *inode) |
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 1261db3916cc..b99caa8b780c 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h | |||
| @@ -34,6 +34,7 @@ DECLARE_EVENT_CLASS(writeback_work_class, | |||
| 34 | __field(int, for_kupdate) | 34 | __field(int, for_kupdate) |
| 35 | __field(int, range_cyclic) | 35 | __field(int, range_cyclic) |
| 36 | __field(int, for_background) | 36 | __field(int, for_background) |
| 37 | __field(int, reason) | ||
| 37 | ), | 38 | ), |
| 38 | TP_fast_assign( | 39 | TP_fast_assign( |
| 39 | strncpy(__entry->name, dev_name(bdi->dev), 32); | 40 | strncpy(__entry->name, dev_name(bdi->dev), 32); |
| @@ -43,16 +44,18 @@ DECLARE_EVENT_CLASS(writeback_work_class, | |||
| 43 | __entry->for_kupdate = work->for_kupdate; | 44 | __entry->for_kupdate = work->for_kupdate; |
| 44 | __entry->range_cyclic = work->range_cyclic; | 45 | __entry->range_cyclic = work->range_cyclic; |
| 45 | __entry->for_background = work->for_background; | 46 | __entry->for_background = work->for_background; |
| 47 | __entry->reason = work->reason; | ||
| 46 | ), | 48 | ), |
| 47 | TP_printk("bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d " | 49 | TP_printk("bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d " |
| 48 | "kupdate=%d range_cyclic=%d background=%d", | 50 | "kupdate=%d range_cyclic=%d background=%d reason=%s", |
| 49 | __entry->name, | 51 | __entry->name, |
| 50 | MAJOR(__entry->sb_dev), MINOR(__entry->sb_dev), | 52 | MAJOR(__entry->sb_dev), MINOR(__entry->sb_dev), |
| 51 | __entry->nr_pages, | 53 | __entry->nr_pages, |
| 52 | __entry->sync_mode, | 54 | __entry->sync_mode, |
| 53 | __entry->for_kupdate, | 55 | __entry->for_kupdate, |
| 54 | __entry->range_cyclic, | 56 | __entry->range_cyclic, |
| 55 | __entry->for_background | 57 | __entry->for_background, |
| 58 | wb_reason_name[__entry->reason] | ||
| 56 | ) | 59 | ) |
| 57 | ); | 60 | ); |
| 58 | #define DEFINE_WRITEBACK_WORK_EVENT(name) \ | 61 | #define DEFINE_WRITEBACK_WORK_EVENT(name) \ |
| @@ -165,6 +168,7 @@ TRACE_EVENT(writeback_queue_io, | |||
| 165 | __field(unsigned long, older) | 168 | __field(unsigned long, older) |
| 166 | __field(long, age) | 169 | __field(long, age) |
| 167 | __field(int, moved) | 170 | __field(int, moved) |
| 171 | __field(int, reason) | ||
| 168 | ), | 172 | ), |
| 169 | TP_fast_assign( | 173 | TP_fast_assign( |
| 170 | unsigned long *older_than_this = work->older_than_this; | 174 | unsigned long *older_than_this = work->older_than_this; |
| @@ -173,12 +177,14 @@ TRACE_EVENT(writeback_queue_io, | |||
| 173 | __entry->age = older_than_this ? | 177 | __entry->age = older_than_this ? |
| 174 | (jiffies - *older_than_this) * 1000 / HZ : -1; | 178 | (jiffies - *older_than_this) * 1000 / HZ : -1; |
| 175 | __entry->moved = moved; | 179 | __entry->moved = moved; |
| 180 | __entry->reason = work->reason; | ||
| 176 | ), | 181 | ), |
| 177 | TP_printk("bdi %s: older=%lu age=%ld enqueue=%d", | 182 | TP_printk("bdi %s: older=%lu age=%ld enqueue=%d reason=%s", |
| 178 | __entry->name, | 183 | __entry->name, |
| 179 | __entry->older, /* older_than_this in jiffies */ | 184 | __entry->older, /* older_than_this in jiffies */ |
| 180 | __entry->age, /* older_than_this in relative milliseconds */ | 185 | __entry->age, /* older_than_this in relative milliseconds */ |
| 181 | __entry->moved) | 186 | __entry->moved, |
| 187 | wb_reason_name[__entry->reason]) | ||
| 182 | ); | 188 | ); |
| 183 | 189 | ||
| 184 | TRACE_EVENT(global_dirty_state, | 190 | TRACE_EVENT(global_dirty_state, |
