]> git.karo-electronics.de Git - karo-tx-linux.git/commit
tmpfs: change final i_blocks BUG to WARNING
authorHugh Dickins <hughd@google.com>
Fri, 9 Nov 2012 03:03:41 +0000 (14:03 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 12 Nov 2012 03:57:35 +0000 (14:57 +1100)
commit725634828e0655bfd564171880c6479c72d7993b
tree34d9559dacabc1e064cc622e778259208c700908
parenteb0bb60c8d97c9173c6a662420d269b6c86cec8c
tmpfs: change final i_blocks BUG to WARNING

Under a particular load on one machine, I have hit shmem_evict_inode()'s
BUG_ON(inode->i_blocks), enough times to narrow it down to a particular
race between swapout and eviction.

It comes from the "if (freed > 0)" asymmetry in shmem_recalc_inode(), and
the lack of coherent locking between mapping's nrpages and shmem's swapped
count.  There's a window in shmem_writepage(), between lowering nrpages in
shmem_delete_from_page_cache() and then raising swapped count, when the
freed count appears to be +1 when it should be 0, and then the asymmetry
stops it from being corrected with -1 before hitting the BUG.

One answer is coherent locking: using tree_lock throughout, without
info->lock; reasonable, but the raw_spin_lock in percpu_counter_add() on
used_blocks makes that messier than expected.  Another answer may be a
further effort to eliminate the weird shmem_recalc_inode() altogether, but
previous attempts at that failed.

So far undecided, but for now change the BUG_ON to WARN_ON: in usual
circumstances it remains a useful consistency check.

Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/shmem.c