Skip to content

Commit 3a69279

Browse files
author
Linus Torvalds
committed
Do dirty page accounting when removing a page from the page cache
Krzysztof Oledzki noticed a dirty page accounting leak on some of his machines, causing the machine to eventually lock up when the kernel decided that there was too much dirty data, but nobody could actually write anything out to fix it. The culprit turns out to be filesystems (cough ext3 with data=journal cough) that re-dirty the page when the "->invalidatepage()" callback is called. Fix it up by doing a final dirty page accounting check when we actually remove the page from the page cache. This fixes bugzilla entry 9182: http://bugzilla.kernel.org/show_bug.cgi?id=9182 Tested-by: Ingo Molnar <mingo@elte.hu> Tested-by: Krzysztof Oledzki <olel@ans.pl> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 3e3b391 commit 3a69279

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

mm/filemap.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ void __remove_from_page_cache(struct page *page)
124124
mapping->nrpages--;
125125
__dec_zone_page_state(page, NR_FILE_PAGES);
126126
BUG_ON(page_mapped(page));
127+
128+
/*
129+
* Some filesystems seem to re-dirty the page even after
130+
* the VM has canceled the dirty bit (eg ext3 journaling).
131+
*
132+
* Fix it up by doing a final dirty accounting check after
133+
* having removed the page entirely.
134+
*/
135+
if (PageDirty(page) && mapping_cap_account_dirty(mapping)) {
136+
dec_zone_page_state(page, NR_FILE_DIRTY);
137+
dec_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
138+
}
127139
}
128140

129141
void remove_from_page_cache(struct page *page)

0 commit comments

Comments
 (0)