Skip to content

Commit

Permalink
xfs: exit AIL push work correctly when AIL is empty
Browse files Browse the repository at this point in the history
The recent conversion of the xfsaild functionality to a work queue
introduced a hard-to-hit log space grant hang. The main cause is a
regression where a work exit path fails to clear the PUSHING state
and recheck the target correctly.

Make both exit paths do the same PUSHING bit clearing and target
checking when the "no more work to be done" condition is hit.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>

(cherry picked from commit ea35a20)
  • Loading branch information
Dave Chinner authored and Alex Elder committed May 9, 2011
1 parent 228d62d commit 9e7004e
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions fs/xfs/xfs_trans_ail.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,18 +346,20 @@ xfs_ail_delete(
*/
STATIC void
xfs_ail_worker(
struct work_struct *work)
struct work_struct *work)
{
struct xfs_ail *ailp = container_of(to_delayed_work(work),
struct xfs_ail *ailp = container_of(to_delayed_work(work),
struct xfs_ail, xa_work);
long tout;
xfs_lsn_t target = ailp->xa_target;
xfs_lsn_t lsn;
xfs_log_item_t *lip;
int flush_log, count, stuck;
xfs_mount_t *mp = ailp->xa_mount;
xfs_mount_t *mp = ailp->xa_mount;
struct xfs_ail_cursor *cur = &ailp->xa_cursors;
int push_xfsbufd = 0;
xfs_log_item_t *lip;
xfs_lsn_t lsn;
xfs_lsn_t target = ailp->xa_target;
long tout = 10;
int flush_log = 0;
int stuck = 0;
int count = 0;
int push_xfsbufd = 0;

spin_lock(&ailp->xa_lock);
xfs_trans_ail_cursor_init(ailp, cur);
Expand All @@ -368,8 +370,7 @@ xfs_ail_worker(
*/
xfs_trans_ail_cursor_done(ailp, cur);
spin_unlock(&ailp->xa_lock);
ailp->xa_last_pushed_lsn = 0;
return;
goto out_done;
}

XFS_STATS_INC(xs_push_ail);
Expand All @@ -386,7 +387,6 @@ xfs_ail_worker(
* lots of contention on the AIL lists.
*/
lsn = lip->li_lsn;
flush_log = stuck = count = 0;
while ((XFS_LSN_CMP(lip->li_lsn, target) < 0)) {
int lock_result;
/*
Expand Down Expand Up @@ -480,7 +480,7 @@ xfs_ail_worker(
}

/* assume we have more work to do in a short while */
tout = 10;
out_done:
if (!count) {
/* We're past our target or empty, so idle */
ailp->xa_last_pushed_lsn = 0;
Expand Down

0 comments on commit 9e7004e

Please sign in to comment.