47 lines
1.7 KiB
Diff
47 lines
1.7 KiB
Diff
|
From: Mel Gorman <mgorman@suse.de>
|
||
|
Date: Wed, 9 Mar 2011 12:26:23 +0000
|
||
|
Subject: [PATCH] netvm: Do not mark requests for swapfile writes as dirty or kswapd fails to free the page
|
||
|
Patch-mainline: Not yet
|
||
|
References: bnc#678472
|
||
|
|
||
|
When writing back NFS pages from kswapd, the inode and pages are getting
|
||
|
marked dirty before IO has even started. The expectation of kswapd is
|
||
|
that it calls clear_page_dirty_for_io(), submits IO and the filesystem
|
||
|
remarks the page dirty if necessary. Without this patch, the page always
|
||
|
comes back under writeback and still dirty. kswapd continually launders
|
||
|
but never frees leading to deadlock.
|
||
|
|
||
|
Signed-off-by: Mel Gorman <mgorman@suse.de>
|
||
|
---
|
||
|
fs/nfs/write.c | 14 ++++++++++++--
|
||
|
1 files changed, 12 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
|
||
|
index 2375c7d..fe05d78 100644
|
||
|
--- a/fs/nfs/write.c
|
||
|
+++ b/fs/nfs/write.c
|
||
|
@@ -744,11 +744,21 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
|
||
|
req = nfs_setup_write_request(ctx, page, offset, count);
|
||
|
if (IS_ERR(req))
|
||
|
return PTR_ERR(req);
|
||
|
- nfs_mark_request_dirty(req);
|
||
|
+
|
||
|
+ /*
|
||
|
+ * There is no need to mark swapfile requests as dirty like normal
|
||
|
+ * writepage requests as page dirtying and cleaning is managed
|
||
|
+ * from the mm. If a PageSwapCache page is marked dirty like this,
|
||
|
+ * it will still be dirty after kswapd calls writepage and may
|
||
|
+ * never be released
|
||
|
+ */
|
||
|
+ if (!PageSwapCache(page))
|
||
|
+ nfs_mark_request_dirty(req);
|
||
|
/* Update file length */
|
||
|
nfs_grow_file(page, offset, count);
|
||
|
nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
|
||
|
- nfs_mark_request_dirty(req);
|
||
|
+ if (!PageSwapCache(page))
|
||
|
+ nfs_mark_request_dirty(req);
|
||
|
nfs_clear_page_tag_locked(req);
|
||
|
return 0;
|
||
|
}
|