lkml.org 
[lkml]   [2012]   [Dec]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 17/89] tmpfs: change final i_blocks BUG to WARNING
    3.2-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Hugh Dickins <hughd@google.com>

    commit 0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 upstream.

    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>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    [bwh: Backported to 3.2: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    mm/shmem.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/mm/shmem.c
    +++ b/mm/shmem.c
    @@ -595,7 +595,7 @@ static void shmem_evict_inode(struct ino
    kfree(xattr->name);
    kfree(xattr);
    }
    - BUG_ON(inode->i_blocks);
    + WARN_ON(inode->i_blocks);
    shmem_free_inode(inode->i_sb);
    end_writeback(inode);
    }



    \
     
     \ /
      Last update: 2012-12-03 18:01    [W:4.285 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site