]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: invert the realtime summary cache
authorOmar Sandoval <osandov@fb.com>
Mon, 16 Oct 2023 17:41:55 +0000 (10:41 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 19 Oct 2023 15:34:33 +0000 (08:34 -0700)
In commit 355e3532132b ("xfs: cache minimum realtime summary level"), I
added a cache of the minimum level of the realtime summary that has any
free extents. However, it turns out that the _maximum_ level is more
useful for upcoming optimizations, and basically equivalent for the
existing usage. So, let's change the meaning of the cache to be the
maximum level + 1, or 0 if there are no free extents.

For example, if the cache contains:

{0, 4}

then there are no free extents starting in realtime bitmap block 0, and
there are no free extents larger than or equal to 2^4 blocks starting in
realtime bitmap block 1. The cache is a loose upper bound, so there may
or may not be free extents smaller than 2^4 blocks in realtime bitmap
block 1.

Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_rtbitmap.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_rtalloc.c

index 9f806af4f720a230f0896ba8c1a47761d3f3235b..b332ab490a4875e32c542c885f2b0d9bfeb202a4 100644 (file)
@@ -495,10 +495,10 @@ xfs_rtmodify_summary_int(
                xfs_suminfo_t   val = xfs_suminfo_add(args, infoword, delta);
 
                if (mp->m_rsum_cache) {
-                       if (val == 0 && log == mp->m_rsum_cache[bbno])
-                               mp->m_rsum_cache[bbno]++;
-                       if (val != 0 && log < mp->m_rsum_cache[bbno])
+                       if (val == 0 && log + 1 == mp->m_rsum_cache[bbno])
                                mp->m_rsum_cache[bbno] = log;
+                       if (val != 0 && log >= mp->m_rsum_cache[bbno])
+                               mp->m_rsum_cache[bbno] = log + 1;
                }
                xfs_trans_log_rtsummary(args, infoword);
                if (sum)
index d8769dc5f6dd717ea09e0f522214f44a33b01d94..9cd1d570d24d1d55dea38ee038d9a51733c0f623 100644 (file)
@@ -101,9 +101,9 @@ typedef struct xfs_mount {
 
        /*
         * Optional cache of rt summary level per bitmap block with the
-        * invariant that m_rsum_cache[bbno] <= the minimum i for which
-        * rsum[i][bbno] != 0. Reads and writes are serialized by the rsumip
-        * inode lock.
+        * invariant that m_rsum_cache[bbno] > the maximum i for which
+        * rsum[i][bbno] != 0, or 0 if rsum[i][bbno] == 0 for all i.
+        * Reads and writes are serialized by the rsumip inode lock.
         */
        uint8_t                 *m_rsum_cache;
        struct xfs_mru_cache    *m_filestream;  /* per-mount filestream data */
index d5b6be45755f58d1709139c21aafa1c1cbeb760a..6bde64584a37215c1f530040a33a3392330a93c5 100644 (file)
@@ -54,14 +54,19 @@ xfs_rtany_summary(
        int                     log;    /* loop counter, log2 of ext. size */
        xfs_suminfo_t           sum;    /* summary data */
 
-       /* There are no extents at levels < m_rsum_cache[bbno]. */
-       if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno])
-               low = mp->m_rsum_cache[bbno];
+       /* There are no extents at levels >= m_rsum_cache[bbno]. */
+       if (mp->m_rsum_cache) {
+               high = min(high, mp->m_rsum_cache[bbno] - 1);
+               if (low > high) {
+                       *stat = 0;
+                       return 0;
+               }
+       }
 
        /*
         * Loop over logs of extent sizes.
         */
-       for (log = low; log <= high; log++) {
+       for (log = high; log >= low; log--) {
                /*
                 * Get one summary datum.
                 */
@@ -82,9 +87,9 @@ xfs_rtany_summary(
         */
        *stat = 0;
 out:
-       /* There were no extents at levels < log. */
-       if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno])
-               mp->m_rsum_cache[bbno] = log;
+       /* There were no extents at levels > log. */
+       if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno])
+               mp->m_rsum_cache[bbno] = log + 1;
        return 0;
 }
 
@@ -887,12 +892,14 @@ xfs_alloc_rsum_cache(
        xfs_extlen_t    rbmblocks)      /* number of rt bitmap blocks */
 {
        /*
-        * The rsum cache is initialized to all zeroes, which is trivially a
-        * lower bound on the minimum level with any free extents. We can
-        * continue without the cache if it couldn't be allocated.
+        * The rsum cache is initialized to the maximum value, which is
+        * trivially an upper bound on the maximum level with any free extents.
+        * We can continue without the cache if it couldn't be allocated.
         */
-       mp->m_rsum_cache = kvzalloc(rbmblocks, GFP_KERNEL);
-       if (!mp->m_rsum_cache)
+       mp->m_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL);
+       if (mp->m_rsum_cache)
+               memset(mp->m_rsum_cache, -1, rbmblocks);
+       else
                xfs_warn(mp, "could not allocate realtime summary cache");
 }