| From nobody Mon Sep 17 00:00:00 2001 |
| From: Christoph Lameter <clameter@sgi.com> |
| Date: Mon, 1 May 2006 12:16:08 -0700 |
| Subject: page migration: Fix fallback behavior for dirty pages |
| |
| Currently we check PageDirty() in order to make the decision to swap out |
| the page. However, the dirty information may be only be contained in the |
| ptes pointing to the page. We need to first unmap the ptes before checking |
| for PageDirty(). If unmap is successful then the page count of the page |
| will also be decreased so that pageout() works properly. |
| |
| This is a fix necessary for 2.6.17. Without this fix we may migrate dirty |
| pages for filesystems without migration functions. Filesystems may keep |
| pointers to dirty pages. Migration of dirty pages can result in the |
| filesystem keeping pointers to freed pages. |
| |
| Unmapping is currently not be separated out from removing all the |
| references to a page and moving the mapping. Therefore try_to_unmap will |
| be called again in migrate_page() if the writeout is successful. However, |
| it wont do anything since the ptes are already removed. |
| |
| The coming updates to the page migration code will restructure the code |
| so that this is no longer necessary. |
| |
| Signed-off-by: Christoph Lameter <clameter@sgi.com> |
| Signed-off-by: Andrew Morton <akpm@osdl.org> |
| Signed-off-by: Linus Torvalds <torvalds@osdl.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| Signed-off-by: Chris Wright <chrisw@sous-sol.org> |
| |
| --- |
| mm/vmscan.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| --- linux-2.6.16.16.orig/mm/vmscan.c |
| +++ linux-2.6.16.16/mm/vmscan.c |
| @@ -949,6 +949,17 @@ redo: |
| goto unlock_both; |
| } |
| |
| + /* Make sure the dirty bit is up to date */ |
| + if (try_to_unmap(page, 1) == SWAP_FAIL) { |
| + rc = -EPERM; |
| + goto unlock_both; |
| + } |
| + |
| + if (page_mapcount(page)) { |
| + rc = -EAGAIN; |
| + goto unlock_both; |
| + } |
| + |
| /* |
| * Default handling if a filesystem does not provide |
| * a migration function. We can only migrate clean |