On Thu, Jun 04, 2020 at 05:45:54PM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > We no longer need to issue IO from shrinker based inode reclaim to > prevent spurious OOM killer invocation. This leaves only the global > filesystem management operations such as unmount needing to > writeback dirty inodes and reclaim them. > > Instead of using the reclaim pass to write dirty inodes before > reclaiming them, use the AIL to push all the dirty inodes before we > try to reclaim them. This allows us to remove all the conditional > SYNC_WAIT locking and the writeback code from xfs_reclaim_inode() > and greatly simplify the checks we need to do to reclaim an inode. > > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> > Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > --- > fs/xfs/xfs_icache.c | 117 ++++++++++++-------------------------------- > 1 file changed, 31 insertions(+), 86 deletions(-) > > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index a6780942034fc..74032316ce5cc 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c ... > @@ -1341,9 +1288,8 @@ xfs_reclaim_inodes_ag( > for (i = 0; i < nr_found; i++) { > if (!batch[i]) > continue; > - error = xfs_reclaim_inode(batch[i], pag, flags); > - if (error && last_error != -EFSCORRUPTED) > - last_error = error; > + if (!xfs_reclaim_inode(batch[i], pag, flags)) > + skipped++; Just a note that I find it a little bit of a landmine that skipped is bumped on trylock failure of the perag reclaim lock when the xfs_reclaim_inodes() caller can now spin on that. It doesn't appear to be an issue with current users, though (xfs_reclaim_workers() passes SYNC_TRYLOCK but not SYNC_WAIT). > } > > *nr_to_scan -= XFS_LOOKUP_BATCH; ... > @@ -1380,8 +1314,18 @@ xfs_reclaim_inodes( > int mode) > { > int nr_to_scan = INT_MAX; > + int skipped; > > - return xfs_reclaim_inodes_ag(mp, mode, &nr_to_scan); > + xfs_reclaim_inodes_ag(mp, mode, &nr_to_scan); > + if (!(mode & SYNC_WAIT)) > + return 0; > + Any reason we fall into the loop below if SYNC_WAIT was passed but the above xfs_reclaim_inodes_ag() call would have returned 0? Looks reasonable other than that inefficiency: Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > + do { > + xfs_ail_push_all_sync(mp->m_ail); > + skipped = xfs_reclaim_inodes_ag(mp, mode, &nr_to_scan); > + } while (skipped > 0); > + > + return 0; > } > > /* > @@ -1402,7 +1346,8 @@ xfs_reclaim_inodes_nr( > xfs_reclaim_work_queue(mp); > xfs_ail_push_all(mp->m_ail); > > - return xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK, &nr_to_scan); > + xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK, &nr_to_scan); > + return 0; > } > > /* > -- > 2.26.2.761.g0e0b3e54be >