Message ID | 20140416040337.10604.7488.stgit@notabene.brown (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Apr 16, 2014 at 02:03:37PM +1000, NeilBrown wrote: > memory allocates can happen while the xfs ilock is held in > xfs_free_eofblocks, particularly > > [<ffffffff813e6667>] kmem_zone_alloc+0x67/0xc0 > [<ffffffff813e5945>] xfs_trans_add_item+0x25/0x50 > [<ffffffff8143d64c>] xfs_trans_ijoin+0x2c/0x60 > [<ffffffff8142275e>] xfs_itruncate_extents+0xbe/0x400 > [<ffffffff813c72f4>] xfs_free_eofblocks+0x1c4/0x240 > > So set PF_FSTRANS to avoid this causing a deadlock. Another "You broke KM_NOFS" moment. You win a Kit Kat. ;) xfs_trans_add_item(): lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS); KM_NOFS needs to work, otherwise XFS is just a huge steaming pile of memory reclaim deadlocks regardless of whether you are using loopback NFS or not. Cheers, Dave.
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index f264616080ca..53761fe4fada 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -889,6 +889,7 @@ xfs_free_eofblocks( xfs_filblks_t map_len; int nimaps; xfs_bmbt_irec_t imap; + unsigned int pflags; /* * Figure out if there are any blocks beyond the end @@ -929,12 +930,14 @@ xfs_free_eofblocks( } } + current_set_flags_nested(&pflags, PF_FSTRANS); error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); if (error) { ASSERT(XFS_FORCED_SHUTDOWN(mp)); xfs_trans_cancel(tp, 0); if (need_iolock) xfs_iunlock(ip, XFS_IOLOCK_EXCL); + current_restore_flags_nested(&pflags, PF_FSTRANS); return error; } @@ -964,6 +967,7 @@ xfs_free_eofblocks( xfs_inode_clear_eofblocks_tag(ip); } + current_restore_flags_nested(&pflags, PF_FSTRANS); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (need_iolock) xfs_iunlock(ip, XFS_IOLOCK_EXCL);
memory allocates can happen while the xfs ilock is held in xfs_free_eofblocks, particularly [<ffffffff813e6667>] kmem_zone_alloc+0x67/0xc0 [<ffffffff813e5945>] xfs_trans_add_item+0x25/0x50 [<ffffffff8143d64c>] xfs_trans_ijoin+0x2c/0x60 [<ffffffff8142275e>] xfs_itruncate_extents+0xbe/0x400 [<ffffffff813c72f4>] xfs_free_eofblocks+0x1c4/0x240 So set PF_FSTRANS to avoid this causing a deadlock. Care is needed here as xfs_trans_reserve() also sets PF_FSTRANS, while xfs_trans_cancel and xfs_trans_commit will clear it. So our extra setting must fully nest these calls. Signed-off-by: NeilBrown <neilb@suse.de> --- fs/xfs/xfs_bmap_util.c | 4 ++++ 1 file changed, 4 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html