]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: convert busy extent tracking to the generic group structure
authorChristoph Hellwig <hch@lst.de>
Mon, 25 Nov 2024 21:14:15 +0000 (13:14 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:24 +0000 (18:01 -0800)
Source kernel commit: adbc76aa0fedcb6da2d1ceb1ce786d1f963afee8

Split busy extent tracking from struct xfs_perag into its own private
structure, which can be pointed to by the generic group structure.

Note that this structure is now dynamically allocated instead of embedded
as the upcoming zone XFS code doesn't need it and will also have an
unusually high number of groups due to hardware constraints.  Dynamically
allocating the structure this is a big memory saver for this case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/libxfs_priv.h
libxfs/xfs_ag.c
libxfs/xfs_ag.h
libxfs/xfs_alloc.c
libxfs/xfs_alloc_btree.c
libxfs/xfs_group.c
libxfs/xfs_group.h
libxfs/xfs_rmap_btree.c

index 9505806131bc42ccd0df4da05fd6950ee521732f..1b6bb961b7ac0685f540a6bd0fecba39b29adb38 100644 (file)
@@ -467,11 +467,11 @@ xfs_buf_readahead(
 
 #define xfs_extent_busy_reuse(...)                     ((void) 0)
 /* avoid unused variable warning */
-#define xfs_extent_busy_insert(tp,pag,bno,len,flags)({         \
-       struct xfs_perag *__foo = pag;                  \
+#define xfs_extent_busy_insert(tp,xg,bno,len,flags)({  \
+       struct xfs_group *__foo = xg;                   \
        __foo = __foo; /* no set-but-unused warning */  \
 })
-#define xfs_extent_busy_trim(args,bno,len,busy_gen)    ({      \
+#define xfs_extent_busy_trim(group,minlen,maxlen,bno,len,busy_gen)     ({      \
        unsigned __foo = *(busy_gen);                           \
        *(busy_gen) = __foo;                                    \
        false;                                                  \
index 1542fea06e305e3bcfcc5ebd6879e5d6d6ef5327..bd38ac175bbae3da84af8ec541fc9bdc05827d41 100644 (file)
@@ -228,11 +228,8 @@ xfs_perag_alloc(
 #ifdef __KERNEL__
        /* Place kernel structure only init below this point. */
        spin_lock_init(&pag->pag_ici_lock);
-       spin_lock_init(&pag->pagb_lock);
        INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
        INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
-       init_waitqueue_head(&pag->pagb_wait);
-       pag->pagb_tree = RB_ROOT;
 #endif /* __KERNEL__ */
 
        error = xfs_buf_cache_init(&pag->pag_bcache);
index 042ee0913fb9b9c97fc631affa5db6b765eb2c3e..7290148fa6e6aaeefe01d344b6950f841b4d8505 100644 (file)
@@ -80,11 +80,6 @@ struct xfs_perag {
        uint8_t         pagf_repair_rmap_level;
 #endif
 
-       spinlock_t      pagb_lock;      /* lock for pagb_tree */
-       struct rb_root  pagb_tree;      /* ordered tree of busy extents */
-       unsigned int    pagb_gen;       /* generation count for pagb_tree */
-       wait_queue_head_t pagb_wait;    /* woken when pagb_gen changes */
-
        atomic_t        pagf_fstrms;    /* # of filestreams active in this AG */
 
        spinlock_t      pag_ici_lock;   /* incore inode cache lock */
index 39e1961078ae3a40e585d69fe9c490032f7133b0..1c50358a8be7ae4a1b3abd0c5f3cc7e699ba341d 100644 (file)
@@ -327,7 +327,8 @@ xfs_alloc_compute_aligned(
        bool            busy;
 
        /* Trim busy sections out of found extent */
-       busy = xfs_extent_busy_trim(args, &bno, &len, busy_gen);
+       busy = xfs_extent_busy_trim(pag_group(args->pag), args->minlen,
+                       args->maxlen, &bno, &len, busy_gen);
 
        /*
         * If we have a largish extent that happens to start before min_agbno,
@@ -1247,7 +1248,7 @@ xfs_alloc_ag_vextent_small(
        if (fbno == NULLAGBLOCK)
                goto out;
 
-       xfs_extent_busy_reuse(args->pag, fbno, 1,
+       xfs_extent_busy_reuse(pag_group(args->pag), fbno, 1,
                              (args->datatype & XFS_ALLOC_NOBUSY));
 
        if (args->datatype & XFS_ALLOC_USERDATA) {
@@ -1360,7 +1361,8 @@ xfs_alloc_ag_vextent_exact(
         */
        tbno = fbno;
        tlen = flen;
-       xfs_extent_busy_trim(args, &tbno, &tlen, &busy_gen);
+       xfs_extent_busy_trim(pag_group(args->pag), args->minlen, args->maxlen,
+                       &tbno, &tlen, &busy_gen);
 
        /*
         * Give up if the start of the extent is busy, or the freespace isn't
@@ -1753,8 +1755,9 @@ restart:
                         * the allocation can be retried.
                         */
                        trace_xfs_alloc_near_busy(args);
-                       error = xfs_extent_busy_flush(args->tp, args->pag,
-                                       acur.busy_gen, alloc_flags);
+                       error = xfs_extent_busy_flush(args->tp,
+                                       pag_group(args->pag), acur.busy_gen,
+                                       alloc_flags);
                        if (error)
                                goto out;
 
@@ -1869,8 +1872,9 @@ restart:
                         * the allocation can be retried.
                         */
                        trace_xfs_alloc_size_busy(args);
-                       error = xfs_extent_busy_flush(args->tp, args->pag,
-                                       busy_gen, alloc_flags);
+                       error = xfs_extent_busy_flush(args->tp,
+                                       pag_group(args->pag), busy_gen,
+                                       alloc_flags);
                        if (error)
                                goto error0;
 
@@ -1968,8 +1972,9 @@ restart:
                         * the allocation can be retried.
                         */
                        trace_xfs_alloc_size_busy(args);
-                       error = xfs_extent_busy_flush(args->tp, args->pag,
-                                       busy_gen, alloc_flags);
+                       error = xfs_extent_busy_flush(args->tp,
+                                       pag_group(args->pag), busy_gen,
+                                       alloc_flags);
                        if (error)
                                goto error0;
 
@@ -3609,8 +3614,8 @@ xfs_alloc_vextent_finish(
                if (error)
                        goto out_drop_perag;
 
-               ASSERT(!xfs_extent_busy_search(args->pag, args->agbno,
-                               args->len));
+               ASSERT(!xfs_extent_busy_search(pag_group(args->pag),
+                               args->agbno, args->len));
        }
 
        xfs_ag_resv_alloc_extent(args->pag, args->resv, args);
@@ -4008,7 +4013,7 @@ __xfs_free_extent(
 
        if (skip_discard)
                busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
-       xfs_extent_busy_insert(tp, pag, agbno, len, busy_flags);
+       xfs_extent_busy_insert(tp, pag_group(pag), agbno, len, busy_flags);
        return 0;
 
 err_release:
index 667655a639fef1bb4b18986f9434ace2235e2ccc..bf906aeb2f8a9edbf901968488955b9689ee7876 100644 (file)
@@ -84,7 +84,7 @@ xfs_allocbt_alloc_block(
        }
 
        atomic64_inc(&cur->bc_mp->m_allocbt_blks);
-       xfs_extent_busy_reuse(cur->bc_ag.pag, bno, 1, false);
+       xfs_extent_busy_reuse(pag_group(cur->bc_ag.pag), bno, 1, false);
 
        new->s = cpu_to_be32(bno);
 
@@ -108,7 +108,7 @@ xfs_allocbt_free_block(
                return error;
 
        atomic64_dec(&cur->bc_mp->m_allocbt_blks);
-       xfs_extent_busy_insert(cur->bc_tp, agbp->b_pag, bno, 1,
+       xfs_extent_busy_insert(cur->bc_tp, pag_group(agbp->b_pag), bno, 1,
                              XFS_EXTENT_BUSY_SKIP_DISCARD);
        return 0;
 }
index 58ace330a765cfcdf8312a4525ea6fd09c3d9872..9c7fa99d00b8020d8718f3a25eaa9ca8093b8648 100644 (file)
@@ -160,6 +160,9 @@ xfs_group_free(
        XFS_IS_CORRUPT(mp, atomic_read(&xg->xg_ref) != 0);
 
        xfs_defer_drain_free(&xg->xg_intents_drain);
+#ifdef __KERNEL__
+       kfree(xg->xg_busy_extents);
+#endif
 
        if (uninit)
                uninit(xg);
@@ -184,6 +187,9 @@ xfs_group_insert(
        xg->xg_type = type;
 
 #ifdef __KERNEL__
+       xg->xg_busy_extents = xfs_extent_busy_alloc();
+       if (!xg->xg_busy_extents)
+               return -ENOMEM;
        spin_lock_init(&xg->xg_state_lock);
        xfs_hooks_init(&xg->xg_rmap_update_hooks);
 #endif
@@ -195,9 +201,14 @@ xfs_group_insert(
        error = xa_insert(&mp->m_groups[type].xa, index, xg, GFP_KERNEL);
        if (error) {
                WARN_ON_ONCE(error == -EBUSY);
-               xfs_defer_drain_free(&xg->xg_intents_drain);
-               return error;
+               goto out_drain;
        }
 
        return 0;
+out_drain:
+       xfs_defer_drain_free(&xg->xg_intents_drain);
+#ifdef __KERNEL__
+       kfree(xg->xg_busy_extents);
+#endif
+       return error;
 }
index a87b9b80ef75168bfb56f82883f079e7748031bf..0ff6e1d5635cb19924db2db03cf4dd0023b44979 100644 (file)
@@ -15,6 +15,11 @@ struct xfs_group {
 #ifdef __KERNEL__
        /* -- kernel only structures below this line -- */
 
+       /*
+        * Track freed but not yet committed extents.
+        */
+       struct xfs_extent_busy_tree *xg_busy_extents;
+
        /*
         * Bitsets of per-ag metadata that have been checked and/or are sick.
         * Callers should hold xg_state_lock before accessing this field.
index ebb2519cf8baf3e7316e855ed94ba0e29a3f4aa1..5829e68790314a38ddb4249fe16df0590a19388d 100644 (file)
@@ -101,7 +101,7 @@ xfs_rmapbt_alloc_block(
                return 0;
        }
 
-       xfs_extent_busy_reuse(pag, bno, 1, false);
+       xfs_extent_busy_reuse(pag_group(pag), bno, 1, false);
 
        new->s = cpu_to_be32(bno);
        be32_add_cpu(&agf->agf_rmap_blocks, 1);
@@ -135,7 +135,7 @@ xfs_rmapbt_free_block(
        if (error)
                return error;
 
-       xfs_extent_busy_insert(cur->bc_tp, pag, bno, 1,
+       xfs_extent_busy_insert(cur->bc_tp, pag_group(pag), bno, 1,
                              XFS_EXTENT_BUSY_SKIP_DISCARD);
 
        xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);