mm: fix assertion mapping->nrpages == 0 in end_writeback()
authorJan Kara <jack@suse.cz>
Mon, 27 Jun 2011 23:18:10 +0000 (16:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Jun 2011 01:00:13 +0000 (18:00 -0700)
commit08142579b6ca35883c1ed066a2681de6f6917062
tree00735ed37753533f3b645714770b4fb036b5f7e0
parent9b679320a5fbf46454011e5c62e0b8991b0956d1
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 <jinshan.xiong@whamcloud.com>, lost in LKML, and dug out
by Miklos Szeredi <mszeredi@suse.de>.

Cc: Jay <jinshan.xiong@whamcloud.com>
Cc: Miklos Szeredi <mszeredi@suse.de>
Signed-off-by: Jan Kara <jack@suse.cz>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/inode.c
include/linux/fs.h
mm/truncate.c