On Fri, Aug 10, 2012 at 03:01:51PM -0300, Carlos Maiolino wrote: > While xfs_buftarg_shrink() is freeing buffers from the dispose list (filled with > buffers from lru list), there is a possibility to have xfs_buf_stale() racing > with it, and removing buffers from dispose list before xfs_buftarg_shrink() does > it. > > This happens because xfs_buftarg_shrink() handle the dispose list without > locking and the test condition in xfs_buf_stale() checks for the buffer being in > *any* list: > > if (!list_empty(&bp->b_lru) > > If the buffer happens to be on dispose list, this causes the buffer counter of > lru list (btp->bt_lru_nr) to be decremented twice (once in xfs_buftarg_shrink() > and another in xfs_buf_stale()) causing a wrong account usage of the lru list. > > This may cause xfs_buftarg_shrink() to return a wrong value to the memory > shrinker shrink_slab(), and such account error may also cause an underflowed > value to be returned; since the counter is lower than the current number of > items in the lru list, a decrement may happen when the counter is 0, causing > an underflow on the counter. > > The fix uses a new flag field (and a new buffer flag) to serialize buffer > handling during the shrink process. The new flag field has been designed to use > btp->bt_lru_lock/unlock instead of xfs_buf_lock/unlock mechanism. > > dchinner, sandeen, aquini and aris also deserve credits for this. > > Signed-off-by: Carlos Maiolino <cmaiolino@xxxxxxxxxx> Looks good. Reviewed-by: Dave Chinner <dchinner@xxxxxxxxxx> -- Dave Chinner david@xxxxxxxxxxxxx _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs