From: "Darrick J. Wong" <djwong@kernel.org>
To: djwong@kernel.org
Cc: linux-xfs@vger.kernel.org, david@fromorbit.com, hch@infradead.org
Subject: [PATCH 13/14] xfs: merge xfs_reclaim_inodes_ag into xfs_inode_walk_ag
Date: Tue, 01 Jun 2021 17:53:44 -0700 [thread overview]
Message-ID: <162259522416.662681.8769645421908758261.stgit@locust> (raw)
In-Reply-To: <162259515220.662681.6750744293005850812.stgit@locust>
From: Darrick J. Wong <djwong@kernel.org>
Merge these two inode walk loops together, since they're pretty similar
now.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/xfs_icache.c | 151 +++++++++++++--------------------------------------
fs/xfs/xfs_icache.h | 7 ++
2 files changed, 45 insertions(+), 113 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index b17ac2f23909..f6e54e638cf4 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -40,6 +40,7 @@
enum xfs_icwalk_goal {
XFS_ICWALK_DQRELE = -1,
XFS_ICWALK_BLOCKGC = XFS_ICI_BLOCKGC_TAG,
+ XFS_ICWALK_RECLAIM = XFS_ICI_RECLAIM_TAG,
};
/* Is there a radix tree tag for this goal? */
@@ -743,17 +744,6 @@ xfs_icache_inode_is_allocated(
return 0;
}
-/*
- * The inode lookup is done in batches to keep the amount of lock traffic and
- * radix tree lookups to a minimum. The batch size is a trade off between
- * lookup reduction and stack usage. This is in the reclaim path, so we can't
- * be too greedy.
- *
- * XXX: This will be moved closer to xfs_inode_walk* once we get rid of the
- * separate reclaim walk functions.
- */
-#define XFS_LOOKUP_BATCH 32
-
#ifdef CONFIG_XFS_QUOTA
/* Decide if we want to grab this inode to drop its dquots. */
static bool
@@ -865,7 +855,7 @@ xfs_dqrele_all_inodes(
* Return true if we grabbed it, false otherwise.
*/
static bool
-xfs_reclaim_inode_grab(
+xfs_reclaim_igrab(
struct xfs_inode *ip)
{
ASSERT(rcu_read_lock_held());
@@ -975,108 +965,13 @@ xfs_reclaim_inode(
xfs_iflags_clear(ip, XFS_IRECLAIM);
}
-/*
- * Walk the AGs and reclaim the inodes in them. Even if the filesystem is
- * corrupted, we still want to try to reclaim all the inodes. If we don't,
- * then a shut down during filesystem unmount reclaim walk leak all the
- * unreclaimed inodes.
- *
- * Returns non-zero if any AGs or inodes were skipped in the reclaim pass
- * so that callers that want to block until all dirty inodes are written back
- * and reclaimed can sanely loop.
- */
-static void
-xfs_reclaim_inodes_ag(
- struct xfs_mount *mp,
- int *nr_to_scan)
-{
- struct xfs_perag *pag;
- xfs_agnumber_t ag = 0;
-
- while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
- unsigned long first_index = 0;
- int done = 0;
- int nr_found = 0;
-
- ag = pag->pag_agno + 1;
-
- first_index = READ_ONCE(pag->pag_ici_reclaim_cursor);
- do {
- struct xfs_inode *batch[XFS_LOOKUP_BATCH];
- int i;
-
- rcu_read_lock();
- nr_found = radix_tree_gang_lookup_tag(
- &pag->pag_ici_root,
- (void **)batch, first_index,
- XFS_LOOKUP_BATCH,
- XFS_ICI_RECLAIM_TAG);
- if (!nr_found) {
- done = 1;
- rcu_read_unlock();
- break;
- }
-
- /*
- * Grab the inodes before we drop the lock. if we found
- * nothing, nr == 0 and the loop will be skipped.
- */
- for (i = 0; i < nr_found; i++) {
- struct xfs_inode *ip = batch[i];
-
- if (done || !xfs_reclaim_inode_grab(ip))
- batch[i] = NULL;
-
- /*
- * Update the index for the next lookup. Catch
- * overflows into the next AG range which can
- * occur if we have inodes in the last block of
- * the AG and we are currently pointing to the
- * last inode.
- *
- * Because we may see inodes that are from the
- * wrong AG due to RCU freeing and
- * reallocation, only update the index if it
- * lies in this AG. It was a race that lead us
- * to see this inode, so another lookup from
- * the same index will not find it again.
- */
- if (XFS_INO_TO_AGNO(mp, ip->i_ino) !=
- pag->pag_agno)
- continue;
- first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
- if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
- done = 1;
- }
-
- /* unlock now we've grabbed the inodes. */
- rcu_read_unlock();
-
- for (i = 0; i < nr_found; i++) {
- if (batch[i])
- xfs_reclaim_inode(batch[i], pag);
- }
-
- *nr_to_scan -= XFS_LOOKUP_BATCH;
- cond_resched();
- } while (nr_found && !done && *nr_to_scan > 0);
-
- if (done)
- first_index = 0;
- WRITE_ONCE(pag->pag_ici_reclaim_cursor, first_index);
- xfs_perag_put(pag);
- }
-}
-
void
xfs_reclaim_inodes(
struct xfs_mount *mp)
{
- int nr_to_scan = INT_MAX;
-
while (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_RECLAIM_TAG)) {
xfs_ail_push_all_sync(mp->m_ail);
- xfs_reclaim_inodes_ag(mp, &nr_to_scan);
+ xfs_inode_walk(mp, XFS_ICWALK_RECLAIM, NULL);
}
}
@@ -1092,11 +987,16 @@ xfs_reclaim_inodes_nr(
struct xfs_mount *mp,
int nr_to_scan)
{
+ struct xfs_eofblocks eofb = {
+ .eof_flags = XFS_EOFB_SCAN_LIMIT,
+ .nr_to_scan = nr_to_scan,
+ };
+
/* kick background reclaimer and push the AIL */
xfs_reclaim_work_queue(mp);
xfs_ail_push_all(mp->m_ail);
- xfs_reclaim_inodes_ag(mp, &nr_to_scan);
+ xfs_inode_walk(mp, XFS_ICWALK_RECLAIM, &eofb);
return 0;
}
@@ -1206,9 +1106,8 @@ xfs_reclaim_worker(
{
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_inode_walk(mp, XFS_ICWALK_RECLAIM, NULL);
xfs_reclaim_work_queue(mp);
}
@@ -1678,6 +1577,14 @@ xfs_blockgc_free_quota(
/* XFS Incore Inode Walking Code */
+/*
+ * The inode lookup is done in batches to keep the amount of lock traffic and
+ * radix tree lookups to a minimum. The batch size is a trade off between
+ * lookup reduction and stack usage. This is in the reclaim path, so we can't
+ * be too greedy.
+ */
+#define XFS_LOOKUP_BATCH 32
+
static inline bool
xfs_grabbed_for_walk(
enum xfs_icwalk_goal goal,
@@ -1688,6 +1595,8 @@ xfs_grabbed_for_walk(
return xfs_blockgc_igrab(ip);
case XFS_ICWALK_DQRELE:
return xfs_dqrele_igrab(ip);
+ case XFS_ICWALK_RECLAIM:
+ return xfs_reclaim_igrab(ip);
default:
return false;
}
@@ -1713,7 +1622,10 @@ xfs_inode_walk_ag(
restart:
done = false;
skipped = 0;
- first_index = 0;
+ if (goal == XFS_ICWALK_RECLAIM)
+ first_index = READ_ONCE(pag->pag_ici_reclaim_cursor);
+ else
+ first_index = 0;
nr_found = 0;
do {
struct xfs_inode *batch[XFS_LOOKUP_BATCH];
@@ -1733,6 +1645,7 @@ xfs_inode_walk_ag(
XFS_LOOKUP_BATCH, goal);
if (!nr_found) {
+ done = true;
rcu_read_unlock();
break;
}
@@ -1779,6 +1692,9 @@ xfs_inode_walk_ag(
case XFS_ICWALK_BLOCKGC:
error = xfs_blockgc_scan_inode(batch[i], eofb);
break;
+ case XFS_ICWALK_RECLAIM:
+ xfs_reclaim_inode(batch[i], pag);
+ break;
}
if (error == -EAGAIN) {
skipped++;
@@ -1794,8 +1710,19 @@ xfs_inode_walk_ag(
cond_resched();
+ if (eofb && (eofb->eof_flags & XFS_EOFB_SCAN_LIMIT)) {
+ eofb->nr_to_scan -= XFS_LOOKUP_BATCH;
+ if (eofb->nr_to_scan <= 0)
+ break;
+ }
} while (nr_found && !done);
+ if (goal == XFS_ICWALK_RECLAIM) {
+ if (done)
+ first_index = 0;
+ WRITE_ONCE(pag->pag_ici_reclaim_cursor, first_index);
+ }
+
if (skipped) {
delay(1);
goto restart;
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index 6f6260c91ba0..63e116c339a8 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -15,6 +15,7 @@ struct xfs_eofblocks {
kgid_t eof_gid;
prid_t eof_prid;
__u64 eof_min_file_size;
+ int nr_to_scan;
};
/* Special eof_flags for dropping dquots. */
@@ -22,9 +23,13 @@ struct xfs_eofblocks {
#define XFS_EOFB_DROP_GDQUOT (1U << 30)
#define XFS_EOFB_DROP_PDQUOT (1U << 29)
+/* Stop scanning after nr_to_scan inodes. */
+#define XFS_EOFB_SCAN_LIMIT (1U << 28)
+
#define XFS_EOFB_PRIVATE_FLAGS (XFS_EOFB_DROP_UDQUOT | \
XFS_EOFB_DROP_GDQUOT | \
- XFS_EOFB_DROP_PDQUOT)
+ XFS_EOFB_DROP_PDQUOT | \
+ XFS_EOFB_SCAN_LIMIT)
/*
* Flags for xfs_iget()
next prev parent reply other threads:[~2021-06-02 0:53 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-02 0:52 [PATCHSET v5 00/14] xfs: clean up incore inode walk functions Darrick J. Wong
2021-06-02 0:52 ` [PATCH 01/14] xfs: move the quotaoff dqrele inode walk into xfs_icache.c Darrick J. Wong
2021-06-02 1:23 ` Dave Chinner
2021-06-02 0:52 ` [PATCH 02/14] xfs: detach inode dquots at the end of inactivation Darrick J. Wong
2021-06-02 0:52 ` [PATCH 03/14] xfs: move the inode walk functions further down Darrick J. Wong
2021-06-02 1:26 ` Dave Chinner
2021-06-02 0:52 ` [PATCH 04/14] xfs: pass the goal of the incore inode walk to xfs_inode_walk() Darrick J. Wong
2021-06-02 1:42 ` Dave Chinner
2021-06-02 0:53 ` [PATCH 05/14] xfs: separate the dqrele_all inode grab logic from xfs_inode_walk_ag_grab Darrick J. Wong
2021-06-02 1:51 ` Dave Chinner
2021-06-02 3:28 ` Darrick J. Wong
2021-06-02 0:53 ` [PATCH 06/14] xfs: move xfs_inew_wait call into xfs_dqrele_inode Darrick J. Wong
2021-06-02 1:52 ` Dave Chinner
2021-06-02 0:53 ` [PATCH 07/14] xfs: remove iter_flags parameter from xfs_inode_walk_* Darrick J. Wong
2021-06-02 1:53 ` Dave Chinner
2021-06-02 0:53 ` [PATCH 08/14] xfs: remove indirect calls from xfs_inode_walk{,_ag} Darrick J. Wong
2021-06-02 2:00 ` Dave Chinner
2021-06-02 0:53 ` [PATCH 09/14] xfs: clean up the blockgc grab and scan calls a little Darrick J. Wong
2021-06-02 0:53 ` [PATCH 10/14] xfs: clean up xfs_dqrele_inode calling conventions Darrick J. Wong
2021-06-02 0:53 ` [PATCH 11/14] xfs: fix radix tree tag signs Darrick J. Wong
2021-06-02 2:02 ` Dave Chinner
2021-06-02 0:53 ` [PATCH 12/14] xfs: pass struct xfs_eofblocks to the inode scan callback Darrick J. Wong
2021-06-02 2:04 ` Dave Chinner
2021-06-02 6:15 ` Darrick J. Wong
2021-06-02 0:53 ` Darrick J. Wong [this message]
2021-06-02 2:10 ` [PATCH 13/14] xfs: merge xfs_reclaim_inodes_ag into xfs_inode_walk_ag Dave Chinner
2021-06-02 6:16 ` Darrick J. Wong
2021-06-02 0:53 ` [PATCH 14/14] xfs: refactor per-AG inode tagging functions Darrick J. Wong
2021-06-02 2:22 ` Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=162259522416.662681.8769645421908758261.stgit@locust \
--to=djwong@kernel.org \
--cc=david@fromorbit.com \
--cc=hch@infradead.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox