Commit e4ad08fe64afca4ef79ecc4c624e6e871688da0d
Committed by
Linus Torvalds
1 parent
76f1418b48
Exists in
master
and in
4 other branches
mm: bdi: add separate writeback accounting capability
Add a new BDI capability flag: BDI_CAP_NO_ACCT_WB. If this flag is set, then don't update the per-bdi writeback stats from test_set_page_writeback() and test_clear_page_writeback(). Misc cleanups: - convert bdi_cap_writeback_dirty() and friends to static inline functions - create a flag that includes all three dirty/writeback related flags, since almst all users will want to have them toghether Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 10 changed files with 67 additions and 30 deletions Side-by-side Diff
fs/configfs/inode.c
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | |
48 | 48 | static struct backing_dev_info configfs_backing_dev_info = { |
49 | 49 | .ra_pages = 0, /* No readahead */ |
50 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | |
50 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | |
51 | 51 | }; |
52 | 52 | |
53 | 53 | static const struct inode_operations configfs_inode_operations ={ |
fs/hugetlbfs/inode.c
... | ... | @@ -45,7 +45,7 @@ |
45 | 45 | |
46 | 46 | static struct backing_dev_info hugetlbfs_backing_dev_info = { |
47 | 47 | .ra_pages = 0, /* No readahead */ |
48 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | |
48 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | |
49 | 49 | }; |
50 | 50 | |
51 | 51 | int sysctl_hugetlb_shm_group; |
fs/ocfs2/dlm/dlmfs.c
... | ... | @@ -327,7 +327,7 @@ |
327 | 327 | |
328 | 328 | static struct backing_dev_info dlmfs_backing_dev_info = { |
329 | 329 | .ra_pages = 0, /* No readahead */ |
330 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | |
330 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | |
331 | 331 | }; |
332 | 332 | |
333 | 333 | static struct inode *dlmfs_get_root_inode(struct super_block *sb) |
fs/ramfs/inode.c
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | |
45 | 45 | static struct backing_dev_info ramfs_backing_dev_info = { |
46 | 46 | .ra_pages = 0, /* No readahead */ |
47 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | | |
47 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | | |
48 | 48 | BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | |
49 | 49 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, |
50 | 50 | }; |
fs/sysfs/inode.c
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | |
31 | 31 | static struct backing_dev_info sysfs_backing_dev_info = { |
32 | 32 | .ra_pages = 0, /* No readahead */ |
33 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | |
33 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | |
34 | 34 | }; |
35 | 35 | |
36 | 36 | static const struct inode_operations sysfs_inode_operations ={ |
include/linux/backing-dev.h
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | #include <linux/log2.h> |
13 | 13 | #include <linux/proportions.h> |
14 | 14 | #include <linux/kernel.h> |
15 | +#include <linux/fs.h> | |
15 | 16 | #include <asm/atomic.h> |
16 | 17 | |
17 | 18 | struct page; |
18 | 19 | |
19 | 20 | |
... | ... | @@ -151,22 +152,43 @@ |
151 | 152 | |
152 | 153 | /* |
153 | 154 | * Flags in backing_dev_info::capability |
154 | - * - The first two flags control whether dirty pages will contribute to the | |
155 | - * VM's accounting and whether writepages() should be called for dirty pages | |
156 | - * (something that would not, for example, be appropriate for ramfs) | |
157 | - * - These flags let !MMU mmap() govern direct device mapping vs immediate | |
158 | - * copying more easily for MAP_PRIVATE, especially for ROM filesystems | |
155 | + * | |
156 | + * The first three flags control whether dirty pages will contribute to the | |
157 | + * VM's accounting and whether writepages() should be called for dirty pages | |
158 | + * (something that would not, for example, be appropriate for ramfs) | |
159 | + * | |
160 | + * WARNING: these flags are closely related and should not normally be | |
161 | + * used separately. The BDI_CAP_NO_ACCT_AND_WRITEBACK combines these | |
162 | + * three flags into a single convenience macro. | |
163 | + * | |
164 | + * BDI_CAP_NO_ACCT_DIRTY: Dirty pages shouldn't contribute to accounting | |
165 | + * BDI_CAP_NO_WRITEBACK: Don't write pages back | |
166 | + * BDI_CAP_NO_ACCT_WB: Don't automatically account writeback pages | |
167 | + * | |
168 | + * These flags let !MMU mmap() govern direct device mapping vs immediate | |
169 | + * copying more easily for MAP_PRIVATE, especially for ROM filesystems. | |
170 | + * | |
171 | + * BDI_CAP_MAP_COPY: Copy can be mapped (MAP_PRIVATE) | |
172 | + * BDI_CAP_MAP_DIRECT: Can be mapped directly (MAP_SHARED) | |
173 | + * BDI_CAP_READ_MAP: Can be mapped for reading | |
174 | + * BDI_CAP_WRITE_MAP: Can be mapped for writing | |
175 | + * BDI_CAP_EXEC_MAP: Can be mapped for execution | |
159 | 176 | */ |
160 | -#define BDI_CAP_NO_ACCT_DIRTY 0x00000001 /* Dirty pages shouldn't contribute to accounting */ | |
161 | -#define BDI_CAP_NO_WRITEBACK 0x00000002 /* Don't write pages back */ | |
162 | -#define BDI_CAP_MAP_COPY 0x00000004 /* Copy can be mapped (MAP_PRIVATE) */ | |
163 | -#define BDI_CAP_MAP_DIRECT 0x00000008 /* Can be mapped directly (MAP_SHARED) */ | |
164 | -#define BDI_CAP_READ_MAP 0x00000010 /* Can be mapped for reading */ | |
165 | -#define BDI_CAP_WRITE_MAP 0x00000020 /* Can be mapped for writing */ | |
166 | -#define BDI_CAP_EXEC_MAP 0x00000040 /* Can be mapped for execution */ | |
177 | +#define BDI_CAP_NO_ACCT_DIRTY 0x00000001 | |
178 | +#define BDI_CAP_NO_WRITEBACK 0x00000002 | |
179 | +#define BDI_CAP_MAP_COPY 0x00000004 | |
180 | +#define BDI_CAP_MAP_DIRECT 0x00000008 | |
181 | +#define BDI_CAP_READ_MAP 0x00000010 | |
182 | +#define BDI_CAP_WRITE_MAP 0x00000020 | |
183 | +#define BDI_CAP_EXEC_MAP 0x00000040 | |
184 | +#define BDI_CAP_NO_ACCT_WB 0x00000080 | |
185 | + | |
167 | 186 | #define BDI_CAP_VMFLAGS \ |
168 | 187 | (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP) |
169 | 188 | |
189 | +#define BDI_CAP_NO_ACCT_AND_WRITEBACK \ | |
190 | + (BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB) | |
191 | + | |
170 | 192 | #if defined(VM_MAYREAD) && \ |
171 | 193 | (BDI_CAP_READ_MAP != VM_MAYREAD || \ |
172 | 194 | BDI_CAP_WRITE_MAP != VM_MAYWRITE || \ |
173 | 195 | |
174 | 196 | |
175 | 197 | |
176 | 198 | |
... | ... | @@ -206,18 +228,33 @@ |
206 | 228 | void set_bdi_congested(struct backing_dev_info *bdi, int rw); |
207 | 229 | long congestion_wait(int rw, long timeout); |
208 | 230 | |
209 | -#define bdi_cap_writeback_dirty(bdi) \ | |
210 | - (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK)) | |
211 | 231 | |
212 | -#define bdi_cap_account_dirty(bdi) \ | |
213 | - (!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY)) | |
232 | +static inline bool bdi_cap_writeback_dirty(struct backing_dev_info *bdi) | |
233 | +{ | |
234 | + return !(bdi->capabilities & BDI_CAP_NO_WRITEBACK); | |
235 | +} | |
214 | 236 | |
215 | -#define mapping_cap_writeback_dirty(mapping) \ | |
216 | - bdi_cap_writeback_dirty((mapping)->backing_dev_info) | |
237 | +static inline bool bdi_cap_account_dirty(struct backing_dev_info *bdi) | |
238 | +{ | |
239 | + return !(bdi->capabilities & BDI_CAP_NO_ACCT_DIRTY); | |
240 | +} | |
217 | 241 | |
218 | -#define mapping_cap_account_dirty(mapping) \ | |
219 | - bdi_cap_account_dirty((mapping)->backing_dev_info) | |
242 | +static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi) | |
243 | +{ | |
244 | + /* Paranoia: BDI_CAP_NO_WRITEBACK implies BDI_CAP_NO_ACCT_WB */ | |
245 | + return !(bdi->capabilities & (BDI_CAP_NO_ACCT_WB | | |
246 | + BDI_CAP_NO_WRITEBACK)); | |
247 | +} | |
220 | 248 | |
249 | +static inline bool mapping_cap_writeback_dirty(struct address_space *mapping) | |
250 | +{ | |
251 | + return bdi_cap_writeback_dirty(mapping->backing_dev_info); | |
252 | +} | |
253 | + | |
254 | +static inline bool mapping_cap_account_dirty(struct address_space *mapping) | |
255 | +{ | |
256 | + return bdi_cap_account_dirty(mapping->backing_dev_info); | |
257 | +} | |
221 | 258 | |
222 | 259 | #endif /* _LINUX_BACKING_DEV_H */ |
kernel/cgroup.c
... | ... | @@ -575,7 +575,7 @@ |
575 | 575 | static struct file_operations proc_cgroupstats_operations; |
576 | 576 | |
577 | 577 | static struct backing_dev_info cgroup_backing_dev_info = { |
578 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | |
578 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | |
579 | 579 | }; |
580 | 580 | |
581 | 581 | static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb) |
mm/page-writeback.c
... | ... | @@ -1246,7 +1246,7 @@ |
1246 | 1246 | radix_tree_tag_clear(&mapping->page_tree, |
1247 | 1247 | page_index(page), |
1248 | 1248 | PAGECACHE_TAG_WRITEBACK); |
1249 | - if (bdi_cap_writeback_dirty(bdi)) { | |
1249 | + if (bdi_cap_account_writeback(bdi)) { | |
1250 | 1250 | __dec_bdi_stat(bdi, BDI_WRITEBACK); |
1251 | 1251 | __bdi_writeout_inc(bdi); |
1252 | 1252 | } |
... | ... | @@ -1275,7 +1275,7 @@ |
1275 | 1275 | radix_tree_tag_set(&mapping->page_tree, |
1276 | 1276 | page_index(page), |
1277 | 1277 | PAGECACHE_TAG_WRITEBACK); |
1278 | - if (bdi_cap_writeback_dirty(bdi)) | |
1278 | + if (bdi_cap_account_writeback(bdi)) | |
1279 | 1279 | __inc_bdi_stat(bdi, BDI_WRITEBACK); |
1280 | 1280 | } |
1281 | 1281 | if (!PageDirty(page)) |
mm/shmem.c
... | ... | @@ -201,7 +201,7 @@ |
201 | 201 | |
202 | 202 | static struct backing_dev_info shmem_backing_dev_info __read_mostly = { |
203 | 203 | .ra_pages = 0, /* No readahead */ |
204 | - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | |
204 | + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | |
205 | 205 | .unplug_io_fn = default_unplug_io_fn, |
206 | 206 | }; |
207 | 207 |
mm/swap_state.c