Commit 4d0bab3a authored by Dave Chinner's avatar Dave Chinner Committed by Darrick J. Wong

xfs: remove SYNC_WAIT from xfs_reclaim_inodes()

Clean up xfs_reclaim_inodes() callers. Most callers want blocking
behaviour, so just make the existing SYNC_WAIT behaviour the
default.

For the xfs_reclaim_worker(), just call xfs_reclaim_inodes_ag()
directly because we just want optimistic clean inode reclaim to be
done in the background.

For xfs_quiesce_attr() we can just remove the inode reclaim calls as
they are a historic relic that was required to flush dirty inodes
that contained unlogged changes. We now log all changes to the
inodes, so the sync AIL push from xfs_log_quiesce() called by
xfs_quiesce_attr() will do all the required inode writeback for
freeze.

Seeing as we now want to loop until all reclaimable inodes have been
reclaimed, make xfs_reclaim_inodes() loop on the XFS_ICI_RECLAIM_TAG
tag rather than having xfs_reclaim_inodes_ag() tell it that inodes
were skipped. This is much more reliable and will always loop until
all reclaimable inodes are reclaimed.
Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 50718b8d
...@@ -160,24 +160,6 @@ xfs_reclaim_work_queue( ...@@ -160,24 +160,6 @@ xfs_reclaim_work_queue(
rcu_read_unlock(); rcu_read_unlock();
} }
/*
* This is a fast pass over the inode cache to try to get reclaim moving on as
* many inodes as possible in a short period of time. It kicks itself every few
* seconds, as well as being kicked by the inode cache shrinker when memory
* goes low. It scans as quickly as possible avoiding locked inodes or those
* already being flushed, and once done schedules a future pass.
*/
void
xfs_reclaim_worker(
struct work_struct *work)
{
struct xfs_mount *mp = container_of(to_delayed_work(work),
struct xfs_mount, m_reclaim_work);
xfs_reclaim_inodes(mp, 0);
xfs_reclaim_work_queue(mp);
}
static void static void
xfs_perag_set_reclaim_tag( xfs_perag_set_reclaim_tag(
struct xfs_perag *pag) struct xfs_perag *pag)
...@@ -1100,7 +1082,7 @@ xfs_reclaim_inode_grab( ...@@ -1100,7 +1082,7 @@ xfs_reclaim_inode_grab(
* dirty, async => requeue * dirty, async => requeue
* dirty, sync => flush, wait and reclaim * dirty, sync => flush, wait and reclaim
*/ */
static bool static void
xfs_reclaim_inode( xfs_reclaim_inode(
struct xfs_inode *ip, struct xfs_inode *ip,
struct xfs_perag *pag) struct xfs_perag *pag)
...@@ -1173,7 +1155,7 @@ xfs_reclaim_inode( ...@@ -1173,7 +1155,7 @@ xfs_reclaim_inode(
ASSERT(xfs_inode_clean(ip)); ASSERT(xfs_inode_clean(ip));
__xfs_inode_free(ip); __xfs_inode_free(ip);
return true; return;
out_ifunlock: out_ifunlock:
xfs_ifunlock(ip); xfs_ifunlock(ip);
...@@ -1181,7 +1163,6 @@ xfs_reclaim_inode( ...@@ -1181,7 +1163,6 @@ xfs_reclaim_inode(
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
out: out:
xfs_iflags_clear(ip, XFS_IRECLAIM); xfs_iflags_clear(ip, XFS_IRECLAIM);
return false;
} }
/* /*
...@@ -1194,14 +1175,13 @@ xfs_reclaim_inode( ...@@ -1194,14 +1175,13 @@ xfs_reclaim_inode(
* so that callers that want to block until all dirty inodes are written back * so that callers that want to block until all dirty inodes are written back
* and reclaimed can sanely loop. * and reclaimed can sanely loop.
*/ */
static int static void
xfs_reclaim_inodes_ag( xfs_reclaim_inodes_ag(
struct xfs_mount *mp, struct xfs_mount *mp,
int *nr_to_scan) int *nr_to_scan)
{ {
struct xfs_perag *pag; struct xfs_perag *pag;
xfs_agnumber_t ag = 0; xfs_agnumber_t ag = 0;
int skipped = 0;
while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
unsigned long first_index = 0; unsigned long first_index = 0;
...@@ -1210,14 +1190,7 @@ xfs_reclaim_inodes_ag( ...@@ -1210,14 +1190,7 @@ xfs_reclaim_inodes_ag(
ag = pag->pag_agno + 1; ag = pag->pag_agno + 1;
/*
* If the cursor is not zero, we haven't scanned the whole AG
* so we might have skipped inodes here.
*/
first_index = READ_ONCE(pag->pag_ici_reclaim_cursor); first_index = READ_ONCE(pag->pag_ici_reclaim_cursor);
if (first_index)
skipped++;
do { do {
struct xfs_inode *batch[XFS_LOOKUP_BATCH]; struct xfs_inode *batch[XFS_LOOKUP_BATCH];
int i; int i;
...@@ -1270,16 +1243,12 @@ xfs_reclaim_inodes_ag( ...@@ -1270,16 +1243,12 @@ xfs_reclaim_inodes_ag(
rcu_read_unlock(); rcu_read_unlock();
for (i = 0; i < nr_found; i++) { for (i = 0; i < nr_found; i++) {
if (!batch[i]) if (batch[i])
continue; xfs_reclaim_inode(batch[i], pag);
if (!xfs_reclaim_inode(batch[i], pag))
skipped++;
} }
*nr_to_scan -= XFS_LOOKUP_BATCH; *nr_to_scan -= XFS_LOOKUP_BATCH;
cond_resched(); cond_resched();
} while (nr_found && !done && *nr_to_scan > 0); } while (nr_found && !done && *nr_to_scan > 0);
if (done) if (done)
...@@ -1287,27 +1256,18 @@ xfs_reclaim_inodes_ag( ...@@ -1287,27 +1256,18 @@ xfs_reclaim_inodes_ag(
WRITE_ONCE(pag->pag_ici_reclaim_cursor, first_index); WRITE_ONCE(pag->pag_ici_reclaim_cursor, first_index);
xfs_perag_put(pag); xfs_perag_put(pag);
} }
return skipped;
} }
int void
xfs_reclaim_inodes( xfs_reclaim_inodes(
xfs_mount_t *mp, struct xfs_mount *mp)
int mode)
{ {
int nr_to_scan = INT_MAX; int nr_to_scan = INT_MAX;
int skipped;
xfs_reclaim_inodes_ag(mp, &nr_to_scan);
if (!(mode & SYNC_WAIT))
return 0;
do { while (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_RECLAIM_TAG)) {
xfs_ail_push_all_sync(mp->m_ail); xfs_ail_push_all_sync(mp->m_ail);
skipped = xfs_reclaim_inodes_ag(mp, &nr_to_scan); xfs_reclaim_inodes_ag(mp, &nr_to_scan);
} while (skipped > 0); };
return 0;
} }
/* /*
...@@ -1426,6 +1386,25 @@ xfs_inode_matches_eofb( ...@@ -1426,6 +1386,25 @@ xfs_inode_matches_eofb(
return true; return true;
} }
/*
* This is a fast pass over the inode cache to try to get reclaim moving on as
* many inodes as possible in a short period of time. It kicks itself every few
* seconds, as well as being kicked by the inode cache shrinker when memory
* goes low. It scans as quickly as possible avoiding locked inodes or those
* already being flushed, and once done schedules a future pass.
*/
void
xfs_reclaim_worker(
struct work_struct *work)
{
struct xfs_mount *mp = container_of(to_delayed_work(work),
struct xfs_mount, m_reclaim_work);
int nr_to_scan = INT_MAX;
xfs_reclaim_inodes_ag(mp, &nr_to_scan);
xfs_reclaim_work_queue(mp);
}
STATIC int STATIC int
xfs_inode_free_eofblocks( xfs_inode_free_eofblocks(
struct xfs_inode *ip, struct xfs_inode *ip,
......
...@@ -51,7 +51,7 @@ void xfs_inode_free(struct xfs_inode *ip); ...@@ -51,7 +51,7 @@ void xfs_inode_free(struct xfs_inode *ip);
void xfs_reclaim_worker(struct work_struct *work); void xfs_reclaim_worker(struct work_struct *work);
int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); void xfs_reclaim_inodes(struct xfs_mount *mp);
int xfs_reclaim_inodes_count(struct xfs_mount *mp); int xfs_reclaim_inodes_count(struct xfs_mount *mp);
long xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan); long xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
......
...@@ -1011,7 +1011,7 @@ xfs_mountfs( ...@@ -1011,7 +1011,7 @@ xfs_mountfs(
* quota inodes. * quota inodes.
*/ */
cancel_delayed_work_sync(&mp->m_reclaim_work); cancel_delayed_work_sync(&mp->m_reclaim_work);
xfs_reclaim_inodes(mp, SYNC_WAIT); xfs_reclaim_inodes(mp);
xfs_health_unmount(mp); xfs_health_unmount(mp);
out_log_dealloc: out_log_dealloc:
mp->m_flags |= XFS_MOUNT_UNMOUNTING; mp->m_flags |= XFS_MOUNT_UNMOUNTING;
...@@ -1088,13 +1088,12 @@ xfs_unmountfs( ...@@ -1088,13 +1088,12 @@ xfs_unmountfs(
xfs_ail_push_all_sync(mp->m_ail); xfs_ail_push_all_sync(mp->m_ail);
/* /*
* And reclaim all inodes. At this point there should be no dirty * Reclaim all inodes. At this point there should be no dirty inodes and
* inodes and none should be pinned or locked, but use synchronous * none should be pinned or locked. Stop background inode reclaim here
* reclaim just to be sure. We can stop background inode reclaim * if it is still running.
* here as well if it is still running.
*/ */
cancel_delayed_work_sync(&mp->m_reclaim_work); cancel_delayed_work_sync(&mp->m_reclaim_work);
xfs_reclaim_inodes(mp, SYNC_WAIT); xfs_reclaim_inodes(mp);
xfs_health_unmount(mp); xfs_health_unmount(mp);
xfs_qm_unmount(mp); xfs_qm_unmount(mp);
......
...@@ -890,9 +890,6 @@ xfs_quiesce_attr( ...@@ -890,9 +890,6 @@ xfs_quiesce_attr(
/* force the log to unpin objects from the now complete transactions */ /* force the log to unpin objects from the now complete transactions */
xfs_log_force(mp, XFS_LOG_SYNC); xfs_log_force(mp, XFS_LOG_SYNC);
/* reclaim inodes to do any IO before the freeze completes */
xfs_reclaim_inodes(mp, 0);
xfs_reclaim_inodes(mp, SYNC_WAIT);
/* Push the superblock and write an unmount record */ /* Push the superblock and write an unmount record */
error = xfs_log_sbcount(mp); error = xfs_log_sbcount(mp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment