xfs: exit AIL push work correctly when AIL is empty
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 ea35a20021)
	
	
This commit is contained in:
		
					parent
					
						
							
								228d62dd3f
							
						
					
				
			
			
				commit
				
					
						9e7004e741
					
				
			
		
					 1 changed files with 13 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -350,13 +350,15 @@ xfs_ail_worker(
 | 
			
		|||
{
 | 
			
		||||
	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;
 | 
			
		||||
	struct xfs_ail_cursor	*cur = &ailp->xa_cursors;
 | 
			
		||||
	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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
		/*
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue