aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2018-09-28 23:46:21 -0400
committerDave Chinner <david@fromorbit.com>2018-09-28 23:46:21 -0400
commit8683edb7755b853f0dd92e07fe2e7a7e675a84d7 (patch)
treee5532cf7ac21ddc84ebd1cb321ff51f1a19831bf /fs/xfs
parent95808459b110f16b50f03a70ecfa72bb14bd8a96 (diff)
xfs: avoid lockdep false positives in xfs_trans_alloc
We've had a few reports of lockdep tripping over memory reclaim context vs filesystem freeze "deadlocks". They all have looked to be false positives on analysis, but it seems that they are being tripped because we take freeze references before we run a GFP_KERNEL allocation for the struct xfs_trans. We can avoid this false positive vector just by re-ordering the operations in xfs_trans_alloc(). That is. we need allocate the structure before we take the freeze reference and enter the GFP_NOFS allocation context that follows the xfs_trans around. This prevents lockdep from seeing the GFP_KERNEL allocation inside the transaction context, and that prevents it from triggering the freeze level vs alloc context vs reclaim warnings. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_trans.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index bedc5a5133a5..912b42f5fe4a 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -259,6 +259,14 @@ xfs_trans_alloc(
259 struct xfs_trans *tp; 259 struct xfs_trans *tp;
260 int error; 260 int error;
261 261
262 /*
263 * Allocate the handle before we do our freeze accounting and setting up
264 * GFP_NOFS allocation context so that we avoid lockdep false positives
265 * by doing GFP_KERNEL allocations inside sb_start_intwrite().
266 */
267 tp = kmem_zone_zalloc(xfs_trans_zone,
268 (flags & XFS_TRANS_NOFS) ? KM_NOFS : KM_SLEEP);
269
262 if (!(flags & XFS_TRANS_NO_WRITECOUNT)) 270 if (!(flags & XFS_TRANS_NO_WRITECOUNT))
263 sb_start_intwrite(mp->m_super); 271 sb_start_intwrite(mp->m_super);
264 272
@@ -270,8 +278,6 @@ xfs_trans_alloc(
270 mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE); 278 mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE);
271 atomic_inc(&mp->m_active_trans); 279 atomic_inc(&mp->m_active_trans);
272 280
273 tp = kmem_zone_zalloc(xfs_trans_zone,
274 (flags & XFS_TRANS_NOFS) ? KM_NOFS : KM_SLEEP);
275 tp->t_magic = XFS_TRANS_HEADER_MAGIC; 281 tp->t_magic = XFS_TRANS_HEADER_MAGIC;
276 tp->t_flags = flags; 282 tp->t_flags = flags;
277 tp->t_mountp = mp; 283 tp->t_mountp = mp;