summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2002-09-09 21:09:13 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-09-09 21:09:13 -0700
commit1f90eedd73cd58923dfeee393adf827c68dade5a (patch)
treec3b8a22f6d4ac39c5be6edc2305f75d1e6227ce8 /include
parent6a0fb424e9c28fd547161444e89ef9ff4275251b (diff)
[PATCH] exact dirty state accounting
Some adjustments to global dirty page accounting. Previously, dirty page accounting counted all dirty pages. Even dirty anonymous pages. This has potential to upset the throttling logic in balance_dirty_pages(). Particularly as I suspect we should decrease the dirty memory writeback thresholds by a lot. So this patch changes it so that we only account for dirty pagecache pages which have backing store. Not anonymous pages, not swapcache, not in-memory filesystem pages. To support this, the `memory_backed' boolean has been added to struct backing_dev_info. When an address space's backing device is marked as memory-backed, the core kernel knows to not include that mapping's pages in the dirty memory accounting. For memory-backed mappings, dirtiness is a way of pinning the page, and there's nothing the kernel can to do clean the page to make it freeable. driverfs, tmpfs, and ranfs have been coverted to mark their mappings as memory-backed. The ramdisk driver hasn't been converted. I have a separate patch for ramdisk, which fails to fix the longstanding problems in there :( With this patch, /bin/sync now sends /proc/meminfo:Dirty to zero, which is rather comforting.
Diffstat (limited to 'include')
-rw-r--r--include/linux/backing-dev.h1
-rw-r--r--include/linux/page-flags.h45
2 files changed, 14 insertions, 32 deletions
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 075cacc389e1..898f8e1814ef 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -19,6 +19,7 @@ enum bdi_state {
struct backing_dev_info {
unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
unsigned long state; /* Always use atomic bitops on this */
+ int memory_backed; /* Cannot clean pages with writepage */
};
extern struct backing_dev_info default_backing_dev_info;
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 2b2eb67ae7a8..42d1853294ac 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -52,7 +52,7 @@
#define PG_referenced 2
#define PG_uptodate 3
-#define PG_dirty_dontuse 4
+#define PG_dirty 4
#define PG_lru 5
#define PG_active 6
#define PG_slab 7 /* slab debug (Suparna wants this) */
@@ -120,37 +120,11 @@ extern void get_page_state(struct page_state *ret);
#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags)
#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
-#define PageDirty(page) test_bit(PG_dirty_dontuse, &(page)->flags)
-#define SetPageDirty(page) \
- do { \
- if (!test_and_set_bit(PG_dirty_dontuse, \
- &(page)->flags)) \
- inc_page_state(nr_dirty); \
- } while (0)
-#define TestSetPageDirty(page) \
- ({ \
- int ret; \
- ret = test_and_set_bit(PG_dirty_dontuse, \
- &(page)->flags); \
- if (!ret) \
- inc_page_state(nr_dirty); \
- ret; \
- })
-#define ClearPageDirty(page) \
- do { \
- if (test_and_clear_bit(PG_dirty_dontuse, \
- &(page)->flags)) \
- dec_page_state(nr_dirty); \
- } while (0)
-#define TestClearPageDirty(page) \
- ({ \
- int ret; \
- ret = test_and_clear_bit(PG_dirty_dontuse, \
- &(page)->flags); \
- if (ret) \
- dec_page_state(nr_dirty); \
- ret; \
- })
+#define PageDirty(page) test_bit(PG_dirty, &(page)->flags)
+#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags)
+#define TestSetPageDirty(page) test_and_set_bit(PG_dirty, &(page)->flags)
+#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags)
+#define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags)
#define SetPageLRU(page) set_bit(PG_lru, &(page)->flags)
#define PageLRU(page) test_bit(PG_lru, &(page)->flags)
@@ -235,4 +209,11 @@ extern void get_page_state(struct page_state *ret);
extern struct address_space swapper_space;
#define PageSwapCache(page) ((page)->mapping == &swapper_space)
+int test_clear_page_dirty(struct page *page);
+
+static inline void clear_page_dirty(struct page *page)
+{
+ test_clear_page_dirty(page);
+}
+
#endif /* PAGE_FLAGS_H */