mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
mm: fix assertion mapping->nrpages == 0 in end_writeback()
Under heavy memory and filesystem load, users observe the assertion
mapping->nrpages == 0 in end_writeback() trigger. This can be caused by
page reclaim reclaiming the last page from a mapping in the following
race:
CPU0 CPU1
...
shrink_page_list()
__remove_mapping()
__delete_from_page_cache()
radix_tree_delete()
evict_inode()
truncate_inode_pages()
truncate_inode_pages_range()
pagevec_lookup() - finds nothing
end_writeback()
mapping->nrpages != 0 -> BUG
page->mapping = NULL
mapping->nrpages--
Fix the problem by doing a reliable check of mapping->nrpages under
mapping->tree_lock in end_writeback().
Analyzed by Jay <[email protected]>, lost in LKML, and dug out
by Miklos Szeredi <[email protected]>.
Cc: Jay <[email protected]>
Cc: Miklos Szeredi <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
9b679320a5
commit
08142579b6
3 changed files with 13 additions and 0 deletions
|
|
@ -423,7 +423,14 @@ EXPORT_SYMBOL(remove_inode_hash);
|
|||
void end_writeback(struct inode *inode)
|
||||
{
|
||||
might_sleep();
|
||||
/*
|
||||
* We have to cycle tree_lock here because reclaim can be still in the
|
||||
* process of removing the last page (in __delete_from_page_cache())
|
||||
* and we must not free mapping under it.
|
||||
*/
|
||||
spin_lock_irq(&inode->i_data.tree_lock);
|
||||
BUG_ON(inode->i_data.nrpages);
|
||||
spin_unlock_irq(&inode->i_data.tree_lock);
|
||||
BUG_ON(!list_empty(&inode->i_data.private_list));
|
||||
BUG_ON(!(inode->i_state & I_FREEING));
|
||||
BUG_ON(inode->i_state & I_CLEAR);
|
||||
|
|
|
|||
Loading…
Reference in a new issue