From 79c8c5c973a444277c13b390c7c2196fe67b07d5 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 6 May 2011 02:54:08 +0000 Subject: [PATCH] --- yaml --- r: 250067 b: refs/heads/master c: e4d3c4a43b595d5124ae824d300626e6489ae857 h: refs/heads/master i: 250065: f1091b071e5c6a5fcde811f8c7d31411fbb13d63 250063: 31c6307b283c14c1b16a399a597ee1176a4d5d6a v: v3 --- [refs] | 2 +- trunk/fs/xfs/xfs_trans_ail.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 698af640ce00..b6bb15441e89 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fd5670f22fce247754243cf2ed41941e5762d990 +refs/heads/master: e4d3c4a43b595d5124ae824d300626e6489ae857 diff --git a/trunk/fs/xfs/xfs_trans_ail.c b/trunk/fs/xfs/xfs_trans_ail.c index d7eebbf71362..5fc2380092c8 100644 --- a/trunk/fs/xfs/xfs_trans_ail.c +++ b/trunk/fs/xfs/xfs_trans_ail.c @@ -487,15 +487,19 @@ xfs_ail_worker( ailp->xa_last_pushed_lsn = 0; /* - * Check for an updated push target before clearing the - * XFS_AIL_PUSHING_BIT. If the target changed, we've got more - * work to do. Wait a bit longer before starting that work. + * We clear the XFS_AIL_PUSHING_BIT first before checking + * whether the target has changed. If the target has changed, + * this pushes the requeue race directly onto the result of the + * atomic test/set bit, so we are guaranteed that either the + * the pusher that changed the target or ourselves will requeue + * the work (but not both). */ + clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags); smp_rmb(); - if (XFS_LSN_CMP(ailp->xa_target, target) == 0) { - clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags); + if (XFS_LSN_CMP(ailp->xa_target, target) == 0 || + test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) return; - } + tout = 50; } else if (XFS_LSN_CMP(lsn, target) >= 0) { /*