aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-06-12 16:39:11 -0700
committerLinus Torvalds <torvalds@evo.osdl.org>2004-06-12 16:39:11 -0700
commit961caf47918340aea55aa2ca9b68e7f1c8d91ca6 (patch)
tree89f895a85f693712d2facc54bab88e37ac44a54c /mm
parent2c38ac911b5edfb8f6933aeb1b98d39603da26a1 (diff)
downloadhistory-961caf47918340aea55aa2ca9b68e7f1c8d91ca6.tar.gz
[PATCH] vmscan: handle synchronous writepage()
Teach page reclaim to understand synchronous ->writepage implementations. If ->writepage completed I/O prior to returning we can proceed to reclaim the page without giving it another trip around the LRU. This is beneficial for ramdisk-backed S_ISREG files: we can reclaim the file's pages as fast as the ramdisk driver needs to allocate them and this prevents I/O errors due to OOM in rd_blkdev_pagecache_IO(). Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/vmscan.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f0ec7d2c67d316..1be7851a22a880 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -374,7 +374,17 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
/* synchronous write or broken a_ops? */
ClearPageReclaim(page);
}
- goto keep;
+ if (PageWriteback(page) || PageDirty(page))
+ goto keep;
+ /*
+ * A synchronous write - probably a ramdisk. Go
+ * ahead and try to reclaim the page.
+ */
+ if (TestSetPageLocked(page))
+ goto keep;
+ if (PageDirty(page) || PageWriteback(page))
+ goto keep_locked;
+ mapping = page_mapping(page);
}
}
@@ -396,7 +406,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
* the pages which were not successfully invalidated in
* truncate_complete_page(). We try to drop those buffers here
* and if that worked, and the page is no longer mapped into
- * process address space (page_count == 0) it can be freed.
+ * process address space (page_count == 1) it can be freed.
* Otherwise, leave the page on the LRU so it is swappable.
*/
if (PagePrivate(page)) {