Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Miklos Szeredi and committed by
Linus Torvalds
e4ad08fe 76f1418b

+67 -30
+1 -1
fs/configfs/inode.c
··· 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 ={
+1 -1
fs/hugetlbfs/inode.c
··· 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;
+1 -1
fs/ocfs2/dlm/dlmfs.c
··· 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)
+1 -1
fs/ramfs/inode.c
··· 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 };
+1 -1
fs/sysfs/inode.c
··· 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 ={
+57 -20
include/linux/backing-dev.h
··· 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; ··· 152 151 153 152 /* 154 153 * Flags in backing_dev_info::capability 155 - * - The first two flags control whether dirty pages will contribute to the 156 - * VM's accounting and whether writepages() should be called for dirty pages 157 - * (something that would not, for example, be appropriate for ramfs) 158 - * - These flags let !MMU mmap() govern direct device mapping vs immediate 159 - * copying more easily for MAP_PRIVATE, especially for ROM filesystems 154 + * 155 + * The first three flags control whether dirty pages will contribute to the 156 + * VM's accounting and whether writepages() should be called for dirty pages 157 + * (something that would not, for example, be appropriate for ramfs) 158 + * 159 + * WARNING: these flags are closely related and should not normally be 160 + * used separately. The BDI_CAP_NO_ACCT_AND_WRITEBACK combines these 161 + * three flags into a single convenience macro. 162 + * 163 + * BDI_CAP_NO_ACCT_DIRTY: Dirty pages shouldn't contribute to accounting 164 + * BDI_CAP_NO_WRITEBACK: Don't write pages back 165 + * BDI_CAP_NO_ACCT_WB: Don't automatically account writeback pages 166 + * 167 + * These flags let !MMU mmap() govern direct device mapping vs immediate 168 + * copying more easily for MAP_PRIVATE, especially for ROM filesystems. 169 + * 170 + * BDI_CAP_MAP_COPY: Copy can be mapped (MAP_PRIVATE) 171 + * BDI_CAP_MAP_DIRECT: Can be mapped directly (MAP_SHARED) 172 + * BDI_CAP_READ_MAP: Can be mapped for reading 173 + * BDI_CAP_WRITE_MAP: Can be mapped for writing 174 + * BDI_CAP_EXEC_MAP: Can be mapped for execution 160 175 */ 161 - #define BDI_CAP_NO_ACCT_DIRTY 0x00000001 /* Dirty pages shouldn't contribute to accounting */ 162 - #define BDI_CAP_NO_WRITEBACK 0x00000002 /* Don't write pages back */ 163 - #define BDI_CAP_MAP_COPY 0x00000004 /* Copy can be mapped (MAP_PRIVATE) */ 164 - #define BDI_CAP_MAP_DIRECT 0x00000008 /* Can be mapped directly (MAP_SHARED) */ 165 - #define BDI_CAP_READ_MAP 0x00000010 /* Can be mapped for reading */ 166 - #define BDI_CAP_WRITE_MAP 0x00000020 /* Can be mapped for writing */ 167 - #define BDI_CAP_EXEC_MAP 0x00000040 /* Can be mapped for execution */ 176 + #define BDI_CAP_NO_ACCT_DIRTY 0x00000001 177 + #define BDI_CAP_NO_WRITEBACK 0x00000002 178 + #define BDI_CAP_MAP_COPY 0x00000004 179 + #define BDI_CAP_MAP_DIRECT 0x00000008 180 + #define BDI_CAP_READ_MAP 0x00000010 181 + #define BDI_CAP_WRITE_MAP 0x00000020 182 + #define BDI_CAP_EXEC_MAP 0x00000040 183 + #define BDI_CAP_NO_ACCT_WB 0x00000080 184 + 168 185 #define BDI_CAP_VMFLAGS \ 169 186 (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP) 187 + 188 + #define BDI_CAP_NO_ACCT_AND_WRITEBACK \ 189 + (BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB) 170 190 171 191 #if defined(VM_MAYREAD) && \ 172 192 (BDI_CAP_READ_MAP != VM_MAYREAD || \ ··· 228 206 void set_bdi_congested(struct backing_dev_info *bdi, int rw); 229 207 long congestion_wait(int rw, long timeout); 230 208 231 - #define bdi_cap_writeback_dirty(bdi) \ 232 - (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK)) 233 209 234 - #define bdi_cap_account_dirty(bdi) \ 235 - (!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY)) 210 + static inline bool bdi_cap_writeback_dirty(struct backing_dev_info *bdi) 211 + { 212 + return !(bdi->capabilities & BDI_CAP_NO_WRITEBACK); 213 + } 236 214 237 - #define mapping_cap_writeback_dirty(mapping) \ 238 - bdi_cap_writeback_dirty((mapping)->backing_dev_info) 215 + static inline bool bdi_cap_account_dirty(struct backing_dev_info *bdi) 216 + { 217 + return !(bdi->capabilities & BDI_CAP_NO_ACCT_DIRTY); 218 + } 239 219 240 - #define mapping_cap_account_dirty(mapping) \ 241 - bdi_cap_account_dirty((mapping)->backing_dev_info) 220 + static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi) 221 + { 222 + /* Paranoia: BDI_CAP_NO_WRITEBACK implies BDI_CAP_NO_ACCT_WB */ 223 + return !(bdi->capabilities & (BDI_CAP_NO_ACCT_WB | 224 + BDI_CAP_NO_WRITEBACK)); 225 + } 242 226 227 + static inline bool mapping_cap_writeback_dirty(struct address_space *mapping) 228 + { 229 + return bdi_cap_writeback_dirty(mapping->backing_dev_info); 230 + } 231 + 232 + static inline bool mapping_cap_account_dirty(struct address_space *mapping) 233 + { 234 + return bdi_cap_account_dirty(mapping->backing_dev_info); 235 + } 243 236 244 237 #endif /* _LINUX_BACKING_DEV_H */
+1 -1
kernel/cgroup.c
··· 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)
+2 -2
mm/page-writeback.c
··· 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 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))
+1 -1
mm/shmem.c
··· 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
+1 -1
mm/swap_state.c
··· 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