Commit 985babe8 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fix a page dirtying race in vmscan.c

There's a small window in which another CPU could dirty the page after
we've cleaned it, and before we've moved it to mapping->dirty_pages().
The end result is a dirty page on mapping->locked_pages, which is
wrong.

So take mapping->page_lock before clearing the dirty bit.
parent e101875d
...@@ -317,6 +317,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask, ...@@ -317,6 +317,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
if (bdi != current->backing_dev_info && if (bdi != current->backing_dev_info &&
bdi_write_congested(bdi)) bdi_write_congested(bdi))
goto keep_locked; goto keep_locked;
write_lock(&mapping->page_lock);
if (test_clear_page_dirty(page)) { if (test_clear_page_dirty(page)) {
int res; int res;
struct writeback_control wbc = { struct writeback_control wbc = {
...@@ -326,7 +327,6 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask, ...@@ -326,7 +327,6 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
.for_reclaim = 1, .for_reclaim = 1,
}; };
write_lock(&mapping->page_lock);
list_move(&page->list, &mapping->locked_pages); list_move(&page->list, &mapping->locked_pages);
write_unlock(&mapping->page_lock); write_unlock(&mapping->page_lock);
...@@ -343,6 +343,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask, ...@@ -343,6 +343,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
} }
goto keep; goto keep;
} }
write_unlock(&mapping->page_lock);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment