public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] xfs: regression fixes for 2.6.39-rc6
@ 2011-05-06  2:54 Dave Chinner
  2011-05-06  2:54 ` [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG Dave Chinner
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Dave Chinner @ 2011-05-06  2:54 UTC (permalink / raw)
  To: xfs

These are the fixes for recent regressions introduced/exposed
by the recent workqueue conversions. Please review.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG
  2011-05-06  2:54 [PATCH 0/5] xfs: regression fixes for 2.6.39-rc6 Dave Chinner
@ 2011-05-06  2:54 ` Dave Chinner
  2011-05-09 14:07   ` Christoph Hellwig
  2011-05-06  2:54 ` [PATCH 2/5] xfs: exit AIL push work correctly when AIL is empty Dave Chinner
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Dave Chinner @ 2011-05-06  2:54 UTC (permalink / raw)
  To: xfs

From: Dave Chinner <dchinner@redhat.com>

On a 32 bit highmem PowerPC machine, the XFS inode cache was growing
without bound and exhausting low memory causing the OOM killer to be
triggered. After some effort, the problem was reproduced on a 32 bit
x86 highmem machine.

The problem is that the per-ag inode reclaim index cursor was not
getting reset to the start of the AG if the radix tree tag lookup
found no more reclaimable inodes. Hence every further reclaim
attempt started at the same index beyond where any reclaimable
inodes lay, and no further background reclaim ever occurred from the
AG.

Without background inode reclaim the VM driven cache shrinker
simply cannot keep up with cache growth, and OOM is the result.

While the change that exposed the problem was the conversion of the
inode reclaim to use work queues for background reclaim, it was not
the cause of the bug. The bug was introduced when the cursor code
was added, just waiting for some weird configuration to strike....

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Tested-By: Christian Kujau <lists@nerdbynature.de>
---
 fs/xfs/linux-2.6/xfs_sync.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index e0da841..cb1bb20 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -936,6 +936,7 @@ restart:
 					XFS_LOOKUP_BATCH,
 					XFS_ICI_RECLAIM_TAG);
 			if (!nr_found) {
+				done = 1;
 				rcu_read_unlock();
 				break;
 			}
-- 
1.7.4.4

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/5] xfs: exit AIL push work correctly when AIL is empty
  2011-05-06  2:54 [PATCH 0/5] xfs: regression fixes for 2.6.39-rc6 Dave Chinner
  2011-05-06  2:54 ` [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG Dave Chinner
@ 2011-05-06  2:54 ` Dave Chinner
  2011-05-09 14:08   ` Christoph Hellwig
  2011-05-06  2:54 ` [PATCH 3/5] xfs: always push the AIL to the target Dave Chinner
  2011-05-06  2:54 ` [PATCH 5/5] xfs: fix race condition in AIL push trigger Dave Chinner
  3 siblings, 1 reply; 9+ messages in thread
From: Dave Chinner @ 2011-05-06  2:54 UTC (permalink / raw)
  To: xfs

From: Dave Chinner <dchinner@redhat.com>

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>
---
 fs/xfs/xfs_trans_ail.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index acdb92f..226c58b 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -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);
@@ -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;
-- 
1.7.4.4

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/5] xfs: always push the AIL to the target
  2011-05-06  2:54 [PATCH 0/5] xfs: regression fixes for 2.6.39-rc6 Dave Chinner
  2011-05-06  2:54 ` [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG Dave Chinner
  2011-05-06  2:54 ` [PATCH 2/5] xfs: exit AIL push work correctly when AIL is empty Dave Chinner
@ 2011-05-06  2:54 ` Dave Chinner
  2011-05-09 14:13   ` Christoph Hellwig
  2011-05-06  2:54 ` [PATCH 5/5] xfs: fix race condition in AIL push trigger Dave Chinner
  3 siblings, 1 reply; 9+ messages in thread
From: Dave Chinner @ 2011-05-06  2:54 UTC (permalink / raw)
  To: xfs

From: Dave Chinner <dchinner@redhat.com>

The recent conversion of the xfsaild functionality to a work queue
introduced a hard-to-hit log space grant hang. One of the problems
discovered is a target mismatch between the item pushing loop and
the target itself.

The push trigger checks for the target increasing (i.e. new target >
current) while the push loop only pushes items that have a LSN <
current. As a result, we can get the situation where the push target
is X, the items at the tail of the AIL have LSN X and they don't get
pushed. The push work then completes thinking it is done, and cannot
be restarted until the push target increases to >= X + 1. If the
push target then never increases (because the tail is not moving),
then we never run the push work again and we stall.

Fix it by making sure log items with a LSN that matches the target
exactly are pushed during the loop.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/xfs_trans_ail.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 226c58b..9f427c2 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -387,7 +387,7 @@ xfs_ail_worker(
 	 * lots of contention on the AIL lists.
 	 */
 	lsn = lip->li_lsn;
-	while ((XFS_LSN_CMP(lip->li_lsn, target) < 0)) {
+	while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) {
 		int	lock_result;
 		/*
 		 * If we can lock the item without sleeping, unlock the AIL
-- 
1.7.4.4

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/5] xfs: fix race condition in AIL push trigger
  2011-05-06  2:54 [PATCH 0/5] xfs: regression fixes for 2.6.39-rc6 Dave Chinner
                   ` (2 preceding siblings ...)
  2011-05-06  2:54 ` [PATCH 3/5] xfs: always push the AIL to the target Dave Chinner
@ 2011-05-06  2:54 ` Dave Chinner
  2011-05-09 14:16   ` Christoph Hellwig
  3 siblings, 1 reply; 9+ messages in thread
From: Dave Chinner @ 2011-05-06  2:54 UTC (permalink / raw)
  To: xfs

From: Dave Chinner <dchinner@redhat.com>

The recent conversion of the xfsaild functionality to a work queue
introduced a hard-to-hit log space grant hang. One is caused by a
race condition in determining whether there is a psh in progress or
not.

The XFS_AIL_PUSHING_BIT is used to determine whether a push is
currently in progress.  When the AIL push work completes, it checked
whether the target changed and cleared the PUSHING bit to allow a
new push to be requeued. The race condition is as follows:

	Thread 1		push work

	smp_wmb()
				smp_rmb()
				check ailp->xa_target unchanged
	update ailp->xa_target
	test/set PUSHING bit
	does not queue
				clear PUSHING bit
				does not requeue

Now that the push target is updated, new attempts to push the AIL
will not trigger as the push target will be the same, and hence
despite trying to push the AIL we won't ever wake it again.

The fix is to ensure that the AIL push work clears the PUSHING bit
before it checks if the target is unchanged.

As a result, both push triggers operate on the same test/set bit
criteria, so even if we race in the push work and miss the target
update, the thread requesting the push will still set the PUSHING
bit and queue the push work to occur. For safety sake, the same
queue check is done if the push work detects the target change,
though only one of the two will will queue new work due to the use
of test_and_set_bit() checks.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/xfs_trans_ail.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index d7eebbf..5fc2380 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -487,15 +487,19 @@ out_done:
 		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) {
 		/*
-- 
1.7.4.4

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG
  2011-05-06  2:54 ` [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG Dave Chinner
@ 2011-05-09 14:07   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2011-05-09 14:07 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

On Fri, May 06, 2011 at 12:54:04PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> On a 32 bit highmem PowerPC machine, the XFS inode cache was growing
> without bound and exhausting low memory causing the OOM killer to be
> triggered. After some effort, the problem was reproduced on a 32 bit
> x86 highmem machine.
> 
> The problem is that the per-ag inode reclaim index cursor was not
> getting reset to the start of the AG if the radix tree tag lookup
> found no more reclaimable inodes. Hence every further reclaim
> attempt started at the same index beyond where any reclaimable
> inodes lay, and no further background reclaim ever occurred from the
> AG.
> 
> Without background inode reclaim the VM driven cache shrinker
> simply cannot keep up with cache growth, and OOM is the result.
> 
> While the change that exposed the problem was the conversion of the
> inode reclaim to use work queues for background reclaim, it was not
> the cause of the bug. The bug was introduced when the cursor code
> was added, just waiting for some weird configuration to strike....

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/5] xfs: exit AIL push work correctly when AIL is empty
  2011-05-06  2:54 ` [PATCH 2/5] xfs: exit AIL push work correctly when AIL is empty Dave Chinner
@ 2011-05-09 14:08   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2011-05-09 14:08 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

On Fri, May 06, 2011 at 12:54:05PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> 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>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/5] xfs: always push the AIL to the target
  2011-05-06  2:54 ` [PATCH 3/5] xfs: always push the AIL to the target Dave Chinner
@ 2011-05-09 14:13   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2011-05-09 14:13 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

On Fri, May 06, 2011 at 12:54:06PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> The recent conversion of the xfsaild functionality to a work queue
> introduced a hard-to-hit log space grant hang. One of the problems
> discovered is a target mismatch between the item pushing loop and
> the target itself.
> 
> The push trigger checks for the target increasing (i.e. new target >
> current) while the push loop only pushes items that have a LSN <
> current. As a result, we can get the situation where the push target
> is X, the items at the tail of the AIL have LSN X and they don't get
> pushed. The push work then completes thinking it is done, and cannot
> be restarted until the push target increases to >= X + 1. If the
> push target then never increases (because the tail is not moving),
> then we never run the push work again and we stall.
> 
> Fix it by making sure log items with a LSN that matches the target
> exactly are pushed during the loop.
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 5/5] xfs: fix race condition in AIL push trigger
  2011-05-06  2:54 ` [PATCH 5/5] xfs: fix race condition in AIL push trigger Dave Chinner
@ 2011-05-09 14:16   ` Christoph Hellwig
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2011-05-09 14:16 UTC (permalink / raw)
  To: Dave Chinner; +Cc: xfs

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-05-09 14:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-06  2:54 [PATCH 0/5] xfs: regression fixes for 2.6.39-rc6 Dave Chinner
2011-05-06  2:54 ` [PATCH 1/5] xfs: ensure reclaim cursor is reset correctly at end of AG Dave Chinner
2011-05-09 14:07   ` Christoph Hellwig
2011-05-06  2:54 ` [PATCH 2/5] xfs: exit AIL push work correctly when AIL is empty Dave Chinner
2011-05-09 14:08   ` Christoph Hellwig
2011-05-06  2:54 ` [PATCH 3/5] xfs: always push the AIL to the target Dave Chinner
2011-05-09 14:13   ` Christoph Hellwig
2011-05-06  2:54 ` [PATCH 5/5] xfs: fix race condition in AIL push trigger Dave Chinner
2011-05-09 14:16   ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox