kernel_optimize_test/fs/xfs
Carlos Maiolino e599b3253c xfs: fix race while discarding buffers [V4]
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@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-08-24 13:46:10 -05:00
..
Kconfig
kmem.c
kmem.h
Makefile
mrlock.h
time.h
uuid.c
uuid.h
xfs_acl.c
xfs_acl.h
xfs_ag.h
xfs_alloc_btree.c
xfs_alloc_btree.h xfs: struct xfs_buf_log_format isn't variable sized. 2012-07-01 14:50:04 -05:00
xfs_alloc.c xfs: don't defer metadata allocation to the workqueue 2012-07-13 13:09:27 -05:00
xfs_alloc.h
xfs_aops.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
xfs_aops.h Prefix IO_XX flags with XFS_IO_XX to avoid namespace colision. 2012-07-22 11:00:55 -05:00
xfs_attr_leaf.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_attr_leaf.h xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_attr_sf.h
xfs_attr.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_attr.h
xfs_bit.c
xfs_bit.h
xfs_bmap_btree.c
xfs_bmap_btree.h
xfs_bmap.c
xfs_bmap.h
xfs_btree.c
xfs_btree.h
xfs_buf_item.c xfs: do not call xfs_bdstrat_cb in xfs_buf_iodone_callbacks 2012-07-13 13:09:49 -05:00
xfs_buf_item.h xfs: support discontiguous buffers in the xfs_buf_log_item 2012-07-01 14:50:06 -05:00
xfs_buf.c xfs: fix race while discarding buffers [V4] 2012-08-24 13:46:10 -05:00
xfs_buf.h xfs: fix race while discarding buffers [V4] 2012-08-24 13:46:10 -05:00
xfs_da_btree.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_da_btree.h xfs: fix comment typo of struct xfs_da_blkinfo. 2012-07-22 10:34:42 -05:00
xfs_dfrag.c
xfs_dfrag.h
xfs_dinode.h
xfs_dir2_block.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_dir2_data.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_dir2_format.h
xfs_dir2_leaf.c xfs: factor buffer reading from xfs_dir2_leaf_getdents 2012-07-01 14:50:08 -05:00
xfs_dir2_node.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_dir2_priv.h xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_dir2_sf.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_dir2.c xfs: remove struct xfs_dabuf and infrastructure 2012-07-01 14:50:07 -05:00
xfs_dir2.h
xfs_discard.c xfs: check for possible overflow in xfs_ioc_trim 2012-08-16 16:42:52 -05:00
xfs_discard.h
xfs_dquot_item.c
xfs_dquot_item.h
xfs_dquot.c
xfs_dquot.h
xfs_error.c
xfs_error.h
xfs_export.c
xfs_export.h
xfs_extent_busy.c
xfs_extent_busy.h
xfs_extfree_item.c
xfs_extfree_item.h
xfs_file.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
xfs_filestream.c
xfs_filestream.h
xfs_fs_subr.c
xfs_fs.h
xfs_fsops.c
xfs_fsops.h
xfs_globals.c
xfs_ialloc_btree.c
xfs_ialloc_btree.h
xfs_ialloc.c xfs: unlock the AGI buffer when looping in xfs_dialloc 2012-08-16 16:23:59 -05:00
xfs_ialloc.h xfs: remove the alloc_done argument to xfs_dialloc 2012-07-29 16:00:31 -05:00
xfs_iget.c xfs: remove iolock lock classes 2012-07-29 16:23:51 -05:00
xfs_inode_item.c xfs: check for stale inode before acquiring iflock on push 2012-06-21 14:20:06 -05:00
xfs_inode_item.h
xfs_inode.c xfs: do not take the iolock in xfs_inactive 2012-07-29 16:16:49 -05:00
xfs_inode.h xfs: remove iolock lock classes 2012-07-29 16:23:51 -05:00
xfs_inum.h
xfs_ioctl32.c xfs: Convert to new freezing code 2012-07-31 09:45:48 +04:00
xfs_ioctl32.h
xfs_ioctl.c xfs: Convert to new freezing code 2012-07-31 09:45:48 +04:00
xfs_ioctl.h
xfs_iomap.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
xfs_iomap.h
xfs_iops.c xfs: update for 3.6-rc1 2012-07-30 13:37:53 -07:00
xfs_iops.h
xfs_itable.c xfs: merge xfs_itobp into xfs_imap_to_bp 2012-07-22 10:46:56 -05:00
xfs_itable.h
xfs_linux.h
xfs_log_cil.c xfs: rename log structure to xlog 2012-06-21 14:21:11 -05:00
xfs_log_priv.h xfs: remove xlog_t typedef 2012-06-21 14:22:27 -05:00
xfs_log_recover.c xfs: merge xfs_itobp into xfs_imap_to_bp 2012-07-22 10:46:56 -05:00
xfs_log_recover.h
xfs_log.c xfs: remove xlog_t typedef 2012-06-21 14:22:27 -05:00
xfs_log.h
xfs_message.c
xfs_message.h
xfs_mount.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
xfs_mount.h xfs: kill struct declarations in xfs_mount.h 2012-08-16 13:29:35 -05:00
xfs_mru_cache.c
xfs_mru_cache.h
xfs_qm_bhv.c
xfs_qm_syscalls.c
xfs_qm.c
xfs_qm.h
xfs_quota_priv.h
xfs_quota.h
xfs_quotaops.c
xfs_rename.c
xfs_rtalloc.c xfs: fix uninitialised variable in xfs_rtbuf_get() 2012-08-16 12:53:12 -05:00
xfs_rtalloc.h
xfs_sb.h
xfs_stats.c
xfs_stats.h
xfs_super.c xfs: remove iolock lock classes 2012-07-29 16:23:51 -05:00
xfs_super.h
xfs_sync.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
xfs_sync.h
xfs_sysctl.c
xfs_sysctl.h
xfs_trace.c
xfs_trace.h xfs: kill struct declarations in xfs_mount.h 2012-08-16 13:29:35 -05:00
xfs_trans_ail.c xfs: re-enable xfsaild idle mode and fix associated races 2012-07-29 16:27:57 -05:00
xfs_trans_buf.c xfs: add discontiguous buffer support to transactions 2012-07-01 14:50:06 -05:00
xfs_trans_dquot.c
xfs_trans_extfree.c
xfs_trans_inode.c
xfs_trans_priv.h xfs: re-enable xfsaild idle mode and fix associated races 2012-07-29 16:27:57 -05:00
xfs_trans_space.h
xfs_trans.c xfs: Convert to new freezing code 2012-07-31 09:45:48 +04:00
xfs_trans.h Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-08-01 10:26:23 -07:00
xfs_types.h xfs: struct xfs_buf_log_format isn't variable sized. 2012-07-01 14:50:04 -05:00
xfs_utils.c xfs: remove the alloc_done argument to xfs_dialloc 2012-07-29 16:00:31 -05:00
xfs_utils.h
xfs_vnode.h
xfs_vnodeops.c xfs: avoid the iolock in xfs_free_eofblocks for evicted inodes 2012-07-29 16:22:20 -05:00
xfs_vnodeops.h
xfs_xattr.c
xfs.h