Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
f30c2269 | 2 | * include/linux/writeback.h |
1da177e4 LT |
3 | */ |
4 | #ifndef WRITEBACK_H | |
5 | #define WRITEBACK_H | |
6 | ||
e8edc6e0 | 7 | #include <linux/sched.h> |
a27bb332 | 8 | #include <linux/workqueue.h> |
f5ff8422 | 9 | #include <linux/fs.h> |
380c27ca | 10 | #include <linux/flex_proportions.h> |
e8edc6e0 | 11 | |
54848d73 WF |
12 | DECLARE_PER_CPU(int, dirty_throttle_leaks); |
13 | ||
ffd1f609 | 14 | /* |
1a12d8bd WF |
15 | * The 1/4 region under the global dirty thresh is for smooth dirty throttling: |
16 | * | |
17 | * (thresh - thresh/DIRTY_FULL_SCOPE, thresh) | |
18 | * | |
ffd1f609 WF |
19 | * Further beyond, all dirtier tasks will enter a loop waiting (possibly long |
20 | * time) for the dirty pages to drop, unless written enough pages. | |
21 | * | |
22 | * The global dirty threshold is normally equal to the global dirty limit, | |
23 | * except when the system suddenly allocates a lot of anonymous memory and | |
24 | * knocks down the global dirty threshold quickly, in which case the global | |
25 | * dirty limit will follow down slowly to prevent livelocking all dirtier tasks. | |
26 | */ | |
1a12d8bd WF |
27 | #define DIRTY_SCOPE 8 |
28 | #define DIRTY_FULL_SCOPE (DIRTY_SCOPE / 2) | |
ffd1f609 | 29 | |
1da177e4 LT |
30 | struct backing_dev_info; |
31 | ||
1da177e4 LT |
32 | /* |
33 | * fs/fs-writeback.c | |
34 | */ | |
35 | enum writeback_sync_modes { | |
36 | WB_SYNC_NONE, /* Don't wait on anything */ | |
37 | WB_SYNC_ALL, /* Wait on every mapping */ | |
1da177e4 LT |
38 | }; |
39 | ||
0e175a18 CW |
40 | /* |
41 | * why some writeback work was initiated | |
42 | */ | |
43 | enum wb_reason { | |
44 | WB_REASON_BACKGROUND, | |
45 | WB_REASON_TRY_TO_FREE_PAGES, | |
46 | WB_REASON_SYNC, | |
47 | WB_REASON_PERIODIC, | |
48 | WB_REASON_LAPTOP_TIMER, | |
49 | WB_REASON_FREE_MORE_MEM, | |
50 | WB_REASON_FS_FREE_SPACE, | |
fc6df808 WL |
51 | /* |
52 | * There is no bdi forker thread any more and works are done | |
53 | * by emergency worker, however, this is TPs userland visible | |
54 | * and we'll be exposing exactly the same information, | |
55 | * so it has a mismatch name. | |
56 | */ | |
0e175a18 CW |
57 | WB_REASON_FORKER_THREAD, |
58 | ||
59 | WB_REASON_MAX, | |
60 | }; | |
0e175a18 | 61 | |
1da177e4 LT |
62 | /* |
63 | * A control structure which tells the writeback code what to do. These are | |
64 | * always on the stack, and hence need no locking. They are always initialised | |
65 | * in a manner such that unspecified fields are set to zero. | |
66 | */ | |
67 | struct writeback_control { | |
1da177e4 LT |
68 | long nr_to_write; /* Write this many pages, and decrement |
69 | this for each page written */ | |
70 | long pages_skipped; /* Pages which were not written */ | |
71 | ||
72 | /* | |
95468fd4 | 73 | * For a_ops->writepages(): if start or end are non-zero then this is |
1da177e4 LT |
74 | * a hint that the filesystem need only write out the pages inside that |
75 | * byterange. The byte at `end' is included in the writeout request. | |
76 | */ | |
111ebb6e OH |
77 | loff_t range_start; |
78 | loff_t range_end; | |
1da177e4 | 79 | |
4cd9069a RK |
80 | enum writeback_sync_modes sync_mode; |
81 | ||
22905f77 | 82 | unsigned for_kupdate:1; /* A kupdate writeback */ |
b17621fe | 83 | unsigned for_background:1; /* A background writeback */ |
6e6938b6 | 84 | unsigned tagged_writepages:1; /* tag-and-write to avoid livelock */ |
22905f77 | 85 | unsigned for_reclaim:1; /* Invoked from the page allocator */ |
111ebb6e | 86 | unsigned range_cyclic:1; /* range_start is cyclic */ |
7747bd4b | 87 | unsigned for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ |
1da177e4 LT |
88 | }; |
89 | ||
380c27ca TH |
90 | /* |
91 | * A wb_domain represents a domain that wb's (bdi_writeback's) belong to | |
92 | * and are measured against each other in. There always is one global | |
93 | * domain, global_wb_domain, that every wb in the system is a member of. | |
94 | * This allows measuring the relative bandwidth of each wb to distribute | |
95 | * dirtyable memory accordingly. | |
96 | */ | |
97 | struct wb_domain { | |
dcc25ae7 TH |
98 | spinlock_t lock; |
99 | ||
380c27ca TH |
100 | /* |
101 | * Scale the writeback cache size proportional to the relative | |
102 | * writeout speed. | |
103 | * | |
104 | * We do this by keeping a floating proportion between BDIs, based | |
105 | * on page writeback completions [end_page_writeback()]. Those | |
106 | * devices that write out pages fastest will get the larger share, | |
107 | * while the slower will get a smaller share. | |
108 | * | |
109 | * We use page writeout completions because we are interested in | |
110 | * getting rid of dirty pages. Having them written out is the | |
111 | * primary goal. | |
112 | * | |
113 | * We introduce a concept of time, a period over which we measure | |
114 | * these events, because demand can/will vary over time. The length | |
115 | * of this period itself is measured in page writeback completions. | |
116 | */ | |
117 | struct fprop_global completions; | |
118 | struct timer_list period_timer; /* timer for aging of completions */ | |
119 | unsigned long period_time; | |
dcc25ae7 TH |
120 | |
121 | /* | |
122 | * The dirtyable memory and dirty threshold could be suddenly | |
123 | * knocked down by a large amount (eg. on the startup of KVM in a | |
124 | * swapless system). This may throw the system into deep dirty | |
125 | * exceeded state and throttle heavy/light dirtiers alike. To | |
126 | * retain good responsiveness, maintain global_dirty_limit for | |
127 | * tracking slowly down to the knocked down dirty threshold. | |
128 | * | |
129 | * Both fields are protected by ->lock. | |
130 | */ | |
131 | unsigned long dirty_limit_tstamp; | |
132 | unsigned long dirty_limit; | |
380c27ca TH |
133 | }; |
134 | ||
1da177e4 LT |
135 | /* |
136 | * fs/fs-writeback.c | |
137 | */ | |
03ba3782 | 138 | struct bdi_writeback; |
0e175a18 CW |
139 | void writeback_inodes_sb(struct super_block *, enum wb_reason reason); |
140 | void writeback_inodes_sb_nr(struct super_block *, unsigned long nr, | |
141 | enum wb_reason reason); | |
f30a7d0c TH |
142 | bool try_to_writeback_inodes_sb(struct super_block *, enum wb_reason reason); |
143 | bool try_to_writeback_inodes_sb_nr(struct super_block *, unsigned long nr, | |
144 | enum wb_reason reason); | |
0dc83bd3 | 145 | void sync_inodes_sb(struct super_block *); |
0e175a18 | 146 | void wakeup_flusher_threads(long nr_pages, enum wb_reason reason); |
169ebd90 | 147 | void inode_wait_for_writeback(struct inode *inode); |
1da177e4 LT |
148 | |
149 | /* writeback.h requires fs.h; it, too, is not included from here. */ | |
150 | static inline void wait_on_inode(struct inode *inode) | |
151 | { | |
152 | might_sleep(); | |
74316201 | 153 | wait_on_bit(&inode->i_state, __I_NEW, TASK_UNINTERRUPTIBLE); |
1da177e4 | 154 | } |
1c0eeaf5 | 155 | |
1da177e4 LT |
156 | /* |
157 | * mm/page-writeback.c | |
158 | */ | |
c2c4986e | 159 | #ifdef CONFIG_BLOCK |
31373d09 | 160 | void laptop_io_completion(struct backing_dev_info *info); |
1da177e4 | 161 | void laptop_sync_completion(void); |
31373d09 MG |
162 | void laptop_mode_sync(struct work_struct *work); |
163 | void laptop_mode_timer_fn(unsigned long data); | |
c2c4986e JA |
164 | #else |
165 | static inline void laptop_sync_completion(void) { } | |
166 | #endif | |
232ea4d6 | 167 | void throttle_vm_writeout(gfp_t gfp_mask); |
a756cf59 | 168 | bool zone_dirty_ok(struct zone *zone); |
380c27ca | 169 | int wb_domain_init(struct wb_domain *dom, gfp_t gfp); |
1da177e4 | 170 | |
dcc25ae7 | 171 | extern struct wb_domain global_wb_domain; |
c42843f2 | 172 | |
1da177e4 LT |
173 | /* These are exported to sysctl. */ |
174 | extern int dirty_background_ratio; | |
2da02997 | 175 | extern unsigned long dirty_background_bytes; |
1da177e4 | 176 | extern int vm_dirty_ratio; |
2da02997 | 177 | extern unsigned long vm_dirty_bytes; |
704503d8 AD |
178 | extern unsigned int dirty_writeback_interval; |
179 | extern unsigned int dirty_expire_interval; | |
1efff914 | 180 | extern unsigned int dirtytime_expire_interval; |
195cf453 | 181 | extern int vm_highmem_is_dirtyable; |
1da177e4 LT |
182 | extern int block_dump; |
183 | extern int laptop_mode; | |
184 | ||
2da02997 | 185 | extern int dirty_background_ratio_handler(struct ctl_table *table, int write, |
8d65af78 | 186 | void __user *buffer, size_t *lenp, |
2da02997 DR |
187 | loff_t *ppos); |
188 | extern int dirty_background_bytes_handler(struct ctl_table *table, int write, | |
8d65af78 | 189 | void __user *buffer, size_t *lenp, |
2da02997 | 190 | loff_t *ppos); |
04fbfdc1 | 191 | extern int dirty_ratio_handler(struct ctl_table *table, int write, |
8d65af78 | 192 | void __user *buffer, size_t *lenp, |
04fbfdc1 | 193 | loff_t *ppos); |
2da02997 | 194 | extern int dirty_bytes_handler(struct ctl_table *table, int write, |
8d65af78 | 195 | void __user *buffer, size_t *lenp, |
2da02997 | 196 | loff_t *ppos); |
1efff914 TT |
197 | int dirtytime_interval_handler(struct ctl_table *table, int write, |
198 | void __user *buffer, size_t *lenp, loff_t *ppos); | |
04fbfdc1 | 199 | |
1da177e4 | 200 | struct ctl_table; |
8d65af78 | 201 | int dirty_writeback_centisecs_handler(struct ctl_table *, int, |
1da177e4 LT |
202 | void __user *, size_t *, loff_t *); |
203 | ||
16c4042f | 204 | void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty); |
0d960a38 | 205 | unsigned long wb_calc_thresh(struct bdi_writeback *wb, unsigned long thresh); |
a88a341a | 206 | |
8a731799 | 207 | void wb_update_bandwidth(struct bdi_writeback *wb, unsigned long start_time); |
1da177e4 | 208 | void page_writeback_init(void); |
d0e1d66b | 209 | void balance_dirty_pages_ratelimited(struct address_space *mapping); |
aa661bbe | 210 | bool wb_over_bg_thresh(struct bdi_writeback *wb); |
fa5a734e | 211 | |
0ea97180 MS |
212 | typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc, |
213 | void *data); | |
214 | ||
0ea97180 MS |
215 | int generic_writepages(struct address_space *mapping, |
216 | struct writeback_control *wbc); | |
5b41d924 ES |
217 | void tag_pages_for_writeback(struct address_space *mapping, |
218 | pgoff_t start, pgoff_t end); | |
0ea97180 MS |
219 | int write_cache_pages(struct address_space *mapping, |
220 | struct writeback_control *wbc, writepage_t writepage, | |
221 | void *data); | |
1da177e4 | 222 | int do_writepages(struct address_space *mapping, struct writeback_control *wbc); |
2d1d43f6 | 223 | void writeback_set_ratelimit(void); |
92c09c04 NK |
224 | void tag_pages_for_writeback(struct address_space *mapping, |
225 | pgoff_t start, pgoff_t end); | |
1da177e4 | 226 | |
2f800fbd WF |
227 | void account_page_redirty(struct page *page); |
228 | ||
1da177e4 | 229 | #endif /* WRITEBACK_H */ |