diff options
author | Andrew Morton <akpm@osdl.org> | 2004-06-12 16:39:11 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2004-06-12 16:39:11 -0700 |
commit | 961caf47918340aea55aa2ca9b68e7f1c8d91ca6 (patch) | |
tree | 89f895a85f693712d2facc54bab88e37ac44a54c /mm | |
parent | 2c38ac911b5edfb8f6933aeb1b98d39603da26a1 (diff) | |
download | history-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.c | 14 |
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)) { |