aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2008-04-30 03:54:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:50 -0400
commite4ad08fe64afca4ef79ecc4c624e6e871688da0d (patch)
tree5b8b390b874700041dc0c095e8ba9ac3ed42ea77
parent76f1418b485da2707531178e517bbb5cf06b3c76 (diff)
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>
-rw-r--r--fs/configfs/inode.c2
-rw-r--r--fs/hugetlbfs/inode.c2
-rw-r--r--fs/ocfs2/dlm/dlmfs.c2
-rw-r--r--fs/ramfs/inode.c2
-rw-r--r--fs/sysfs/inode.c2
-rw-r--r--include/linux/backing-dev.h77
-rw-r--r--kernel/cgroup.c2
-rw-r--r--mm/page-writeback.c4
-rw-r--r--mm/shmem.c2
-rw-r--r--mm/swap_state.c2
10 files changed, 67 insertions, 30 deletions
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index 4c1ebff778ee..b9a1d810346d 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -47,7 +47,7 @@ static const struct address_space_operations configfs_aops = {
47 47
48static struct backing_dev_info configfs_backing_dev_info = { 48static struct backing_dev_info configfs_backing_dev_info = {
49 .ra_pages = 0, /* No readahead */ 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
53static const struct inode_operations configfs_inode_operations ={ 53static const struct inode_operations configfs_inode_operations ={
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 9783723e8ffe..aeabf80f81a5 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -45,7 +45,7 @@ static const struct inode_operations hugetlbfs_inode_operations;
45 45
46static struct backing_dev_info hugetlbfs_backing_dev_info = { 46static struct backing_dev_info hugetlbfs_backing_dev_info = {
47 .ra_pages = 0, /* No readahead */ 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
51int sysctl_hugetlb_shm_group; 51int sysctl_hugetlb_shm_group;
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index 61a000f8524c..e48aba698b77 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -327,7 +327,7 @@ clear_fields:
327 327
328static struct backing_dev_info dlmfs_backing_dev_info = { 328static struct backing_dev_info dlmfs_backing_dev_info = {
329 .ra_pages = 0, /* No readahead */ 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
333static struct inode *dlmfs_get_root_inode(struct super_block *sb) 333static struct inode *dlmfs_get_root_inode(struct super_block *sb)
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 8428d5b2711d..b13123424e49 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -44,7 +44,7 @@ static const struct inode_operations ramfs_dir_inode_operations;
44 44
45static struct backing_dev_info ramfs_backing_dev_info = { 45static struct backing_dev_info ramfs_backing_dev_info = {
46 .ra_pages = 0, /* No readahead */ 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 BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | 48 BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
49 BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, 49 BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
50}; 50};
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index d9262f74f94e..f8b82e73b3bf 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -30,7 +30,7 @@ static const struct address_space_operations sysfs_aops = {
30 30
31static struct backing_dev_info sysfs_backing_dev_info = { 31static struct backing_dev_info sysfs_backing_dev_info = {
32 .ra_pages = 0, /* No readahead */ 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
36static const struct inode_operations sysfs_inode_operations ={ 36static const struct inode_operations sysfs_inode_operations ={
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index c49a2d045e11..13ab79d99268 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -12,6 +12,7 @@
12#include <linux/log2.h> 12#include <linux/log2.h>
13#include <linux/proportions.h> 13#include <linux/proportions.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/fs.h>
15#include <asm/atomic.h> 16#include <asm/atomic.h>
16 17
17struct page; 18struct page;
@@ -151,22 +152,43 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
151 152
152/* 153/*
153 * Flags in backing_dev_info::capability 154 * Flags in backing_dev_info::capability
154 * - The first two flags control whether dirty pages will contribute to the 155 *
155 * VM's accounting and whether writepages() should be called for dirty pages 156 * The first three flags control whether dirty pages will contribute to the
156 * (something that would not, for example, be appropriate for ramfs) 157 * VM's accounting and whether writepages() should be called for dirty pages
157 * - These flags let !MMU mmap() govern direct device mapping vs immediate 158 * (something that would not, for example, be appropriate for ramfs)
158 * copying more easily for MAP_PRIVATE, especially for ROM filesystems 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 */ 177#define BDI_CAP_NO_ACCT_DIRTY 0x00000001
161#define BDI_CAP_NO_WRITEBACK 0x00000002 /* Don't write pages back */ 178#define BDI_CAP_NO_WRITEBACK 0x00000002
162#define BDI_CAP_MAP_COPY 0x00000004 /* Copy can be mapped (MAP_PRIVATE) */ 179#define BDI_CAP_MAP_COPY 0x00000004
163#define BDI_CAP_MAP_DIRECT 0x00000008 /* Can be mapped directly (MAP_SHARED) */ 180#define BDI_CAP_MAP_DIRECT 0x00000008
164#define BDI_CAP_READ_MAP 0x00000010 /* Can be mapped for reading */ 181#define BDI_CAP_READ_MAP 0x00000010
165#define BDI_CAP_WRITE_MAP 0x00000020 /* Can be mapped for writing */ 182#define BDI_CAP_WRITE_MAP 0x00000020
166#define BDI_CAP_EXEC_MAP 0x00000040 /* Can be mapped for execution */ 183#define BDI_CAP_EXEC_MAP 0x00000040
184#define BDI_CAP_NO_ACCT_WB 0x00000080
185
167#define BDI_CAP_VMFLAGS \ 186#define BDI_CAP_VMFLAGS \
168 (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP) 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#if defined(VM_MAYREAD) && \ 192#if defined(VM_MAYREAD) && \
171 (BDI_CAP_READ_MAP != VM_MAYREAD || \ 193 (BDI_CAP_READ_MAP != VM_MAYREAD || \
172 BDI_CAP_WRITE_MAP != VM_MAYWRITE || \ 194 BDI_CAP_WRITE_MAP != VM_MAYWRITE || \
@@ -206,17 +228,32 @@ void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
206void set_bdi_congested(struct backing_dev_info *bdi, int rw); 228void set_bdi_congested(struct backing_dev_info *bdi, int rw);
207long congestion_wait(int rw, long timeout); 229long 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) \ 232static inline bool bdi_cap_writeback_dirty(struct backing_dev_info *bdi)
213 (!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY)) 233{
234 return !(bdi->capabilities & BDI_CAP_NO_WRITEBACK);
235}
236
237static inline bool bdi_cap_account_dirty(struct backing_dev_info *bdi)
238{
239 return !(bdi->capabilities & BDI_CAP_NO_ACCT_DIRTY);
240}
214 241
215#define mapping_cap_writeback_dirty(mapping) \ 242static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi)
216 bdi_cap_writeback_dirty((mapping)->backing_dev_info) 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}
217 248
218#define mapping_cap_account_dirty(mapping) \ 249static inline bool mapping_cap_writeback_dirty(struct address_space *mapping)
219 bdi_cap_account_dirty((mapping)->backing_dev_info) 250{
251 return bdi_cap_writeback_dirty(mapping->backing_dev_info);
252}
220 253
254static 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#endif /* _LINUX_BACKING_DEV_H */ 259#endif /* _LINUX_BACKING_DEV_H */
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index b9d467d83fc1..fbc6fc8949b4 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -575,7 +575,7 @@ static struct inode_operations cgroup_dir_inode_operations;
575static struct file_operations proc_cgroupstats_operations; 575static struct file_operations proc_cgroupstats_operations;
576 576
577static struct backing_dev_info cgroup_backing_dev_info = { 577static 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
581static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb) 581static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 2a9942f5387c..bbcb916190c9 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1246,7 +1246,7 @@ int test_clear_page_writeback(struct page *page)
1246 radix_tree_tag_clear(&mapping->page_tree, 1246 radix_tree_tag_clear(&mapping->page_tree,
1247 page_index(page), 1247 page_index(page),
1248 PAGECACHE_TAG_WRITEBACK); 1248 PAGECACHE_TAG_WRITEBACK);
1249 if (bdi_cap_writeback_dirty(bdi)) { 1249 if (bdi_cap_account_writeback(bdi)) {
1250 __dec_bdi_stat(bdi, BDI_WRITEBACK); 1250 __dec_bdi_stat(bdi, BDI_WRITEBACK);
1251 __bdi_writeout_inc(bdi); 1251 __bdi_writeout_inc(bdi);
1252 } 1252 }
@@ -1275,7 +1275,7 @@ int test_set_page_writeback(struct page *page)
1275 radix_tree_tag_set(&mapping->page_tree, 1275 radix_tree_tag_set(&mapping->page_tree,
1276 page_index(page), 1276 page_index(page),
1277 PAGECACHE_TAG_WRITEBACK); 1277 PAGECACHE_TAG_WRITEBACK);
1278 if (bdi_cap_writeback_dirty(bdi)) 1278 if (bdi_cap_account_writeback(bdi))
1279 __inc_bdi_stat(bdi, BDI_WRITEBACK); 1279 __inc_bdi_stat(bdi, BDI_WRITEBACK);
1280 } 1280 }
1281 if (!PageDirty(page)) 1281 if (!PageDirty(page))
diff --git a/mm/shmem.c b/mm/shmem.c
index e6d9298aa22a..e2a6ae1a44e9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -201,7 +201,7 @@ static struct vm_operations_struct shmem_vm_ops;
201 201
202static struct backing_dev_info shmem_backing_dev_info __read_mostly = { 202static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
203 .ra_pages = 0, /* No readahead */ 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 .unplug_io_fn = default_unplug_io_fn, 205 .unplug_io_fn = default_unplug_io_fn,
206}; 206};
207 207
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 50757ee3f9f3..d8aadaf2a0ba 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -33,7 +33,7 @@ static const struct address_space_operations swap_aops = {
33}; 33};
34 34
35static struct backing_dev_info swap_backing_dev_info = { 35static 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 .unplug_io_fn = swap_unplug_io_fn, 37 .unplug_io_fn = swap_unplug_io_fn,
38}; 38};
39 39