Commit e4ad08fe64afca4ef79ecc4c624e6e871688da0d

Authored by Miklos Szeredi
Committed by Linus Torvalds
1 parent 76f1418b48

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

... ... @@ -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)
... ... @@ -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 };
... ... @@ -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 */
... ... @@ -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)
... ... @@ -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))
... ... @@ -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  
... ... @@ -33,7 +33,7 @@
33 33 };
34 34  
35 35 static struct backing_dev_info swap_backing_dev_info = {
36   - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
  36 + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
37 37 .unplug_io_fn = swap_unplug_io_fn,
38 38 };
39 39