From: Omar Sandoval <osandov@osandov.com>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: linux-xfs@vger.kernel.org, kernel-team@fb.com,
Prashant Nema <pnema@fb.com>
Subject: Re: [PATCH 5/6] xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
Date: Mon, 17 Jul 2023 14:06:36 -0700 [thread overview]
Message-ID: <ZLWtXNLcRKpBgt45@telecaster> (raw)
In-Reply-To: <20230712233403.GY108251@frogsfrogsfrogs>
On Wed, Jul 12, 2023 at 04:34:03PM -0700, Darrick J. Wong wrote:
> On Tue, Jun 20, 2023 at 02:32:15PM -0700, Omar Sandoval wrote:
> > From: Omar Sandoval <osandov@fb.com>
> >
> > xfs_rtallocate_extent_near() tries to find a free extent as close to a
> > target bitmap block given by bbno as possible, which may be before or
> > after bbno. Searching backwards has a complication: the realtime summary
> > accounts for free space _starting_ in a bitmap block, but not straddling
> > or ending in a bitmap block. So, when the negative search finds a free
> > extent in the realtime summary, in order to end up closer to the target,
> > it looks for the end of the free extent. For example, if bbno - 2 has a
> > free extent, then it will check bbno - 1, then bbno - 2. But then if
> > bbno - 3 has a free extent, it will check bbno - 1 again, then bbno - 2
> > again, and then bbno - 3. This results in a quadratic loop, which is
> > completely pointless since the repeated checks won't find anything new.
> >
> > Fix it by remembering where we last checked up to and continue from
> > there. This also obviates the need for a check of the realtime summary.
> >
> > Signed-off-by: Omar Sandoval <osandov@fb.com>
> > ---
> > fs/xfs/xfs_rtalloc.c | 46 +++-----------------------------------------
> > 1 file changed, 3 insertions(+), 43 deletions(-)
> >
> > diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
> > index d079dfb77c73..4d9d0be2e616 100644
> > --- a/fs/xfs/xfs_rtalloc.c
> > +++ b/fs/xfs/xfs_rtalloc.c
> > @@ -468,6 +468,7 @@ xfs_rtallocate_extent_near(
> > }
> > bbno = XFS_BITTOBLOCK(mp, bno);
> > i = 0;
> > + j = -1;
> > ASSERT(minlen != 0);
> > log2len = xfs_highbit32(minlen);
> > /*
> > @@ -518,31 +519,11 @@ xfs_rtallocate_extent_near(
> > else { /* i < 0 */
> > /*
> > * Loop backwards through the bitmap blocks from
> > - * the starting point-1 up to where we are now.
> > + * where we last checked up to where we are now.
>
> I find this comment a bit unclear -- aren't we looping backwards from
> where we last checked *downwards*? I was reading "where we are now" to
> mean @i, which contains a negative value.
Yes, "where we last checked down to where we are now" might be better
wording.
> "When @i is negative, we try to find a free extent that starts in the
> bitmap blocks before bbno. Starting from the last bitmap block that we
> checked in a negative scan (initially bbno - 1) and walking downwards
> towards (bbno + i), try to allocate an extent of satisfactory length."
>
> But now having worked my way through that, now I'm wondering what the j
> loop is even doing. Doesn't the sequence of blocks that we call
> xfs_rtallocate_extent_block on alternate backwards and forwards? e.g.
>
> Try to find a satisfactory free extent that starts in:
>
> bbno
> bbno + 1
> bbno - 1
> bbno + 2
> bbno - 2
> ...
> etc?
>
> Why not avoid the loop entirely by calling xfs_rtallocate_extent_block
> on bbno + i once before switching back to positive @i? What am I
> missing here?
There are two ways I can think of to remove the j loop, so I'll address
both.
If you mean: make the i >= 0 and i < 0 branches the same and call
xfs_rtallocate_extent_block() if and only if xfs_rtany_summary() returns
a non-zero maxlog, i.e.:
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 4ab03eafd39f..9d7296c40ddd 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -495,10 +495,6 @@ xfs_rtallocate_extent_near(
xfs_extlen_t maxavail =
min_t(xfs_rtblock_t, maxlen,
(1ULL << (maxlog + 1)) - 1);
- /*
- * On the positive side of the starting location.
- */
- if (i >= 0) {
/*
* Try to allocate an extent starting in
* this block.
@@ -517,33 +513,6 @@ xfs_rtallocate_extent_near(
return 0;
}
}
- /*
- * On the negative side of the starting location.
- */
- else { /* i < 0 */
- /*
- * Loop backwards through the bitmap blocks from
- * where we last checked up to where we are now.
- * There should be an extent which ends in this
- * bitmap block and is long enough.
- */
- for (; j >= i; j--) {
- error = xfs_rtallocate_extent_block(mp,
- tp, bbno + j, minlen, maxavail,
- len, &n, rtbufc, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it works, return the extent.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- }
- }
- }
/*
* Loop control. If we were on the positive side, and there's
* still more blocks on the negative side, go there.
Then when i < 0, this will only find the _beginning_ of a free extent
before bbno rather than the apparent goal of trying to allocate as close
as possible to bbno, i.e., the _end_ of the free extent. (This is what I
tried to explain in the commit message.)
If instead you mean: unconditionally call xfs_rtallocate_extent_block()
for bbno + i when i < 0, i.e.:
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 4ab03eafd39f..1cf42910c0e8 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -491,14 +491,10 @@ xfs_rtallocate_extent_near(
* If there are any useful extents starting here, try
* allocating one.
*/
- if (maxlog >= 0) {
+ if (maxlog >= 0 || i < 0) {
xfs_extlen_t maxavail =
min_t(xfs_rtblock_t, maxlen,
(1ULL << (maxlog + 1)) - 1);
- /*
- * On the positive side of the starting location.
- */
- if (i >= 0) {
/*
* Try to allocate an extent starting in
* this block.
@@ -517,33 +513,6 @@ xfs_rtallocate_extent_near(
return 0;
}
}
- /*
- * On the negative side of the starting location.
- */
- else { /* i < 0 */
- /*
- * Loop backwards through the bitmap blocks from
- * where we last checked up to where we are now.
- * There should be an extent which ends in this
- * bitmap block and is long enough.
- */
- for (; j >= i; j--) {
- error = xfs_rtallocate_extent_block(mp,
- tp, bbno + j, minlen, maxavail,
- len, &n, rtbufc, prod, &r);
- if (error) {
- return error;
- }
- /*
- * If it works, return the extent.
- */
- if (r != NULLRTBLOCK) {
- *rtblock = r;
- return 0;
- }
- }
- }
- }
/*
* Loop control. If we were on the positive side, and there's
* still more blocks on the negative side, go there.
Then this will find the end of the extent, but we will waste a lot of
time searching bitmap blocks that don't have any usable free space. (In
fact, this is something that patch 6 tries to reduce further.)
> > * There should be an extent which ends in this
> > * bitmap block and is long enough.
> > */
> > - for (j = -1; j > i; j--) {
> > - /*
> > - * Grab the summary information for
> > - * this bitmap block.
> > - */
> > - error = xfs_rtany_summary(mp, tp,
> > - log2len, mp->m_rsumlevels - 1,
> > - bbno + j, rtbufc, &maxlog);
> > - if (error) {
> > - return error;
> > - }
> > - /*
> > - * If there's no extent given in the
> > - * summary that means the extent we
> > - * found must carry over from an
> > - * earlier block. If there is an
> > - * extent given, we've already tried
> > - * that allocation, don't do it again.
> > - */
> > - if (maxlog >= 0)
> > - continue;
> > + for (; j >= i; j--) {
>
> Changing the j > i to j >= i is what obviates the extra call to
> xfs_rtallocate_extent_block below, correct?
Correct. Before, the loop body was different because it contained a call
to xfs_rtany_summary(). But now there's no check, so the extra call can
be included in the loop.
next prev parent reply other threads:[~2023-07-17 21:06 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-20 21:32 [PATCH 0/6] xfs: CPU usage optimizations for realtime allocator Omar Sandoval
2023-06-20 21:32 ` [PATCH 1/6] xfs: cache last bitmap block in " Omar Sandoval
2023-07-12 18:29 ` Darrick J. Wong
2023-07-17 18:18 ` Omar Sandoval
2023-08-01 22:48 ` Darrick J. Wong
2023-06-20 21:32 ` [PATCH 2/6] xfs: invert the realtime summary cache Omar Sandoval
2023-07-12 22:40 ` Darrick J. Wong
2023-07-17 19:54 ` Omar Sandoval
2023-08-01 23:17 ` Darrick J. Wong
2023-06-20 21:32 ` [PATCH 3/6] xfs: return maximum free size from xfs_rtany_summary() Omar Sandoval
2023-07-12 22:44 ` Darrick J. Wong
2023-06-20 21:32 ` [PATCH 4/6] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Omar Sandoval
2023-07-12 23:01 ` Darrick J. Wong
2023-07-17 20:33 ` Omar Sandoval
2023-06-20 21:32 ` [PATCH 5/6] xfs: don't try redundant allocations " Omar Sandoval
2023-07-12 23:34 ` Darrick J. Wong
2023-07-17 21:06 ` Omar Sandoval [this message]
2023-07-31 20:58 ` Omar Sandoval
2023-08-01 23:00 ` Darrick J. Wong
2023-06-20 21:32 ` [PATCH 6/6] xfs: don't look for end of extent further than necessary " Omar Sandoval
2023-08-01 23:40 ` Darrick J. Wong
2023-07-06 21:39 ` [PATCH 0/6] xfs: CPU usage optimizations for realtime allocator Omar Sandoval
2023-07-07 0:36 ` 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=ZLWtXNLcRKpBgt45@telecaster \
--to=osandov@osandov.com \
--cc=djwong@kernel.org \
--cc=kernel-team@fb.com \
--cc=linux-xfs@vger.kernel.org \
--cc=pnema@fb.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.