From 92d9cd1059f80b9c89dee191ffb88b0872e6a7ae Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 6 Mar 2008 13:45:10 +1100 Subject: [XFS] 977545 977545 977545 977545 977545 977545 xfsaild causing too many wakeups Idle state is not being detected properly by the xfsaild push code. The current idle state is detected by an empty list which may never happen with mostly idle filesystem or one using lazy superblock counters. A single dirty item in the list that exists beyond the push target can result repeated looping attempting to push up to the target because it fails to check if the push target has been acheived or not. Fix by considering a dirty list with everything past the target as an idle state and set the timeout appropriately. SGI-PV: 977545 SGI-Modid: xfs-linux-melb:xfs-kern:30532a Signed-off-by: David Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_trans_ail.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 4d6330eddc8d..76d470d8a1e6 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -261,16 +261,19 @@ xfsaild_push( xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); } - /* - * We reached the target so wait a bit longer for I/O to complete and - * remove pushed items from the AIL before we start the next scan from - * the start of the AIL. - */ - if ((XFS_LSN_CMP(lsn, target) >= 0)) { + if (!count) { + /* We're past our target or empty, so idle */ + tout = 1000; + } else if (XFS_LSN_CMP(lsn, target) >= 0) { + /* + * We reached the target so wait a bit longer for I/O to + * complete and remove pushed items from the AIL before we + * start the next scan from the start of the AIL. + */ tout += 20; last_pushed_lsn = 0; } else if ((restarts > XFS_TRANS_PUSH_AIL_RESTARTS) || - (count && ((stuck * 100) / count > 90))) { + ((stuck * 100) / count > 90)) { /* * Either there is a lot of contention on the AIL or we * are stuck due to operations in progress. "Stuck" in this -- cgit v1.2.3 From 72772a3b5b158cddcfbbff3ef13b26b03a905158 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 6 Mar 2008 13:49:43 +1100 Subject: [XFS] fix inode leak in xfs_iget_core() If the radix_tree_preload() fails, we need to destroy the inode we just read in before trying again. This could leak xfs_vnode structures when there is memory pressure. Noticed by Christoph Hellwig. SGI-PV: 977823 SGI-Modid: xfs-linux-melb:xfs-kern:30606a Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_iget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index f01b07687faf..8e09b71f4104 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -235,6 +235,7 @@ finish_inode: */ new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP); if (radix_tree_preload(GFP_KERNEL)) { + xfs_idestroy(ip); delay(1); goto again; } -- cgit v1.2.3