]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: get rid of unnecessary xfs_perag_{get,put} pairs
authorGao Xiang <hsiangkao@redhat.com>
Fri, 4 Sep 2020 20:00:20 +0000 (16:00 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 4 Sep 2020 20:00:20 +0000 (16:00 -0400)
Source kernel commit: 92a005448f6fed70b5e7a9f29a1f930118449f1b

In the course of some operations, we look up the perag from
the mount multiple times to get or change perag information.
These are often very short pieces of code, so while the
lookup cost is generally low, the cost of the lookup is far
higher than the cost of the operation we are doing on the
perag.

Since we changed buffers to hold references to the perag
they are cached in, many modification contexts already hold
active references to the perag that are held across these
operations. This is especially true for any operation that
is serialised by an allocation group header buffer.

In these cases, we can just use the buffer's reference to
the perag to avoid needing to do lookups to access the
perag. This means that many operations don't need to do
perag lookups at all to access the perag because they've
already looked up objects that own persistent references
and hence can use that reference instead.

Cc: Dave Chinner <dchinner@redhat.com>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_ag.c
libxfs/xfs_ag_resv.h
libxfs/xfs_alloc.c
libxfs/xfs_alloc_btree.c
libxfs/xfs_ialloc.c
libxfs/xfs_refcount_btree.c
libxfs/xfs_rmap_btree.c

index 9ce7abd786864d91fc36fe97d3b12e8cb9aa3e71..ceaa7e5e464092e24ce6b9f57369be9c6bb21b20 100644 (file)
@@ -563,7 +563,8 @@ xfs_ag_get_geometry(
        error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agf_bp);
        if (error)
                goto out_agi;
-       pag = xfs_perag_get(mp, agno);
+
+       pag = agi_bp->b_pag;
 
        /* Fill out form. */
        memset(ageo, 0, sizeof(*ageo));
@@ -583,7 +584,6 @@ xfs_ag_get_geometry(
        xfs_ag_geom_health(pag, ageo);
 
        /* Release resources. */
-       xfs_perag_put(pag);
        xfs_buf_relse(agf_bp);
 out_agi:
        xfs_buf_relse(agi_bp);
index f3fd0ee9a7f784650805afb8b5831355b018617b..8a8eb4bc48bb657d4fb812f7c8fbf602cdae1c72 100644 (file)
@@ -37,16 +37,4 @@ xfs_ag_resv_rmapbt_alloc(
        xfs_perag_put(pag);
 }
 
-static inline void
-xfs_ag_resv_rmapbt_free(
-       struct xfs_mount        *mp,
-       xfs_agnumber_t          agno)
-{
-       struct xfs_perag        *pag;
-
-       pag = xfs_perag_get(mp, agno);
-       xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);
-       xfs_perag_put(pag);
-}
-
 #endif /* __XFS_AG_RESV_H__ */
index fee4039ca1829bc22198b4b67da0cd40f026aa3a..d8f317e5f0fda49b7f7e183717df8db101a68be8 100644 (file)
@@ -706,13 +706,12 @@ xfs_alloc_read_agfl(
 STATIC int
 xfs_alloc_update_counters(
        struct xfs_trans        *tp,
-       struct xfs_perag        *pag,
        struct xfs_buf          *agbp,
        long                    len)
 {
        struct xfs_agf          *agf = agbp->b_addr;
 
-       pag->pagf_freeblks += len;
+       agbp->b_pag->pagf_freeblks += len;
        be32_add_cpu(&agf->agf_freeblks, len);
 
        xfs_trans_agblocks_delta(tp, len);
@@ -1171,8 +1170,7 @@ xfs_alloc_ag_vextent(
        }
 
        if (!args->wasfromfl) {
-               error = xfs_alloc_update_counters(args->tp, args->pag,
-                                                 args->agbp,
+               error = xfs_alloc_update_counters(args->tp, args->agbp,
                                                  -((long)(args->len)));
                if (error)
                        return error;
@@ -1883,7 +1881,6 @@ xfs_free_ag_extent(
        enum xfs_ag_resv_type           type)
 {
        struct xfs_mount                *mp;
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *bno_cur;
        struct xfs_btree_cur            *cnt_cur;
        xfs_agblock_t                   gtbno; /* start of right neighbor */
@@ -2163,10 +2160,8 @@ xfs_free_ag_extent(
        /*
         * Update the freespace totals in the ag and superblock.
         */
-       pag = xfs_perag_get(mp, agno);
-       error = xfs_alloc_update_counters(tp, pag, agbp, len);
-       xfs_ag_resv_free_extent(pag, type, tp, len);
-       xfs_perag_put(pag);
+       error = xfs_alloc_update_counters(tp, agbp, len);
+       xfs_ag_resv_free_extent(agbp->b_pag, type, tp, len);
        if (error)
                goto error0;
 
@@ -2685,7 +2680,7 @@ xfs_alloc_get_freelist(
        if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp))
                agf->agf_flfirst = 0;
 
-       pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
+       pag = agbp->b_pag;
        ASSERT(!pag->pagf_agflreset);
        be32_add_cpu(&agf->agf_flcount, -1);
        xfs_trans_agflist_delta(tp, -1);
@@ -2697,7 +2692,6 @@ xfs_alloc_get_freelist(
                pag->pagf_btreeblks++;
                logflags |= XFS_AGF_BTREEBLKS;
        }
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(tp, agbp, logflags);
        *bnop = bno;
@@ -2793,7 +2787,7 @@ xfs_alloc_put_freelist(
        if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp))
                agf->agf_fllast = 0;
 
-       pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
+       pag = agbp->b_pag;
        ASSERT(!pag->pagf_agflreset);
        be32_add_cpu(&agf->agf_flcount, 1);
        xfs_trans_agflist_delta(tp, 1);
@@ -2805,7 +2799,6 @@ xfs_alloc_put_freelist(
                pag->pagf_btreeblks--;
                logflags |= XFS_AGF_BTREEBLKS;
        }
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(tp, agbp, logflags);
 
@@ -3002,7 +2995,7 @@ xfs_alloc_read_agf(
        ASSERT(!(*bpp)->b_error);
 
        agf = (*bpp)->b_addr;
-       pag = xfs_perag_get(mp, agno);
+       pag = (*bpp)->b_pag;
        if (!pag->pagf_init) {
                pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
                pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
@@ -3030,7 +3023,6 @@ xfs_alloc_read_agf(
                       be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
        }
 #endif
-       xfs_perag_put(pag);
        return 0;
 }
 
index deb2210b8f3e23ff97b717b2a1c7798ed4da689b..87dd4ff86a9ef87ddbf3eb7770ed4bba028d508e 100644 (file)
@@ -36,16 +36,14 @@ xfs_allocbt_set_root(
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
        int                     btnum = cur->bc_btnum;
-       struct xfs_perag        *pag = xfs_perag_get(cur->bc_mp, seqno);
+       struct xfs_perag        *pag = agbp->b_pag;
 
        ASSERT(ptr->s != 0);
 
        agf->agf_roots[btnum] = ptr->s;
        be32_add_cpu(&agf->agf_levels[btnum], inc);
        pag->pagf_levels[btnum] += inc;
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
 }
@@ -113,7 +111,6 @@ xfs_allocbt_update_lastrec(
        int                     reason)
 {
        struct xfs_agf          *agf = cur->bc_ag.agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
        struct xfs_perag        *pag;
        __be32                  len;
        int                     numrecs;
@@ -158,9 +155,8 @@ xfs_allocbt_update_lastrec(
        }
 
        agf->agf_longest = len;
-       pag = xfs_perag_get(cur->bc_mp, seqno);
+       pag = cur->bc_ag.agbp->b_pag;
        pag->pagf_longest = be32_to_cpu(len);
-       xfs_perag_put(pag);
        xfs_alloc_log_agf(cur->bc_tp, cur->bc_ag.agbp, XFS_AGF_LONGEST);
 }
 
index d2e80d0a09724e8b1d9a9452f90eecb8e1332155..5f09ff5afac1367f7e90a85bd4e57a12449d78d3 100644 (file)
@@ -883,10 +883,9 @@ sparse_alloc:
         */
        be32_add_cpu(&agi->agi_count, newlen);
        be32_add_cpu(&agi->agi_freecount, newlen);
-       pag = xfs_perag_get(args.mp, agno);
+       pag = agbp->b_pag;
        pag->pagi_freecount += newlen;
        pag->pagi_count += newlen;
-       xfs_perag_put(pag);
        agi->agi_newino = cpu_to_be32(newino);
 
        /*
@@ -1129,7 +1128,7 @@ xfs_dialloc_ag_inobt(
        xfs_agnumber_t          agno = be32_to_cpu(agi->agi_seqno);
        xfs_agnumber_t          pagno = XFS_INO_TO_AGNO(mp, parent);
        xfs_agino_t             pagino = XFS_INO_TO_AGINO(mp, parent);
-       struct xfs_perag        *pag;
+       struct xfs_perag        *pag = agbp->b_pag;
        struct xfs_btree_cur    *cur, *tcur;
        struct xfs_inobt_rec_incore rec, trec;
        xfs_ino_t               ino;
@@ -1138,8 +1137,6 @@ xfs_dialloc_ag_inobt(
        int                     i, j;
        int                     searchdistance = 10;
 
-       pag = xfs_perag_get(mp, agno);
-
        ASSERT(pag->pagi_init);
        ASSERT(pag->pagi_inodeok);
        ASSERT(pag->pagi_freecount > 0);
@@ -1379,14 +1376,12 @@ alloc_inode:
 
        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
        xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
-       xfs_perag_put(pag);
        *inop = ino;
        return 0;
 error1:
        xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
 error0:
        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
-       xfs_perag_put(pag);
        return error;
 }
 
@@ -1582,7 +1577,6 @@ xfs_dialloc_ag(
        xfs_agnumber_t                  agno = be32_to_cpu(agi->agi_seqno);
        xfs_agnumber_t                  pagno = XFS_INO_TO_AGNO(mp, parent);
        xfs_agino_t                     pagino = XFS_INO_TO_AGINO(mp, parent);
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *cur;   /* finobt cursor */
        struct xfs_btree_cur            *icur;  /* inobt cursor */
        struct xfs_inobt_rec_incore     rec;
@@ -1594,8 +1588,6 @@ xfs_dialloc_ag(
        if (!xfs_sb_version_hasfinobt(&mp->m_sb))
                return xfs_dialloc_ag_inobt(tp, agbp, parent, inop);
 
-       pag = xfs_perag_get(mp, agno);
-
        /*
         * If pagino is 0 (this is the root inode allocation) use newino.
         * This must work because we've just allocated some.
@@ -1662,7 +1654,7 @@ xfs_dialloc_ag(
         */
        be32_add_cpu(&agi->agi_freecount, -1);
        xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
-       pag->pagi_freecount--;
+       agbp->b_pag->pagi_freecount--;
 
        xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
 
@@ -1675,7 +1667,6 @@ xfs_dialloc_ag(
 
        xfs_btree_del_cursor(icur, XFS_BTREE_NOERROR);
        xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
-       xfs_perag_put(pag);
        *inop = ino;
        return 0;
 
@@ -1683,7 +1674,6 @@ error_icur:
        xfs_btree_del_cursor(icur, XFS_BTREE_ERROR);
 error_cur:
        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
-       xfs_perag_put(pag);
        return error;
 }
 
@@ -1940,7 +1930,6 @@ xfs_difree_inobt(
 {
        struct xfs_agi                  *agi = agbp->b_addr;
        xfs_agnumber_t                  agno = be32_to_cpu(agi->agi_seqno);
-       struct xfs_perag                *pag;
        struct xfs_btree_cur            *cur;
        struct xfs_inobt_rec_incore     rec;
        int                             ilen;
@@ -2002,6 +1991,8 @@ xfs_difree_inobt(
        if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
            rec.ir_free == XFS_INOBT_ALL_FREE &&
            mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
+               struct xfs_perag        *pag = agbp->b_pag;
+
                xic->deleted = true;
                xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
                xic->alloc = xfs_inobt_irec_to_allocmask(&rec);
@@ -2015,10 +2006,8 @@ xfs_difree_inobt(
                be32_add_cpu(&agi->agi_count, -ilen);
                be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
                xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
-               pag = xfs_perag_get(mp, agno);
                pag->pagi_freecount -= ilen - 1;
                pag->pagi_count -= ilen;
-               xfs_perag_put(pag);
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
 
@@ -2044,9 +2033,7 @@ xfs_difree_inobt(
                 */
                be32_add_cpu(&agi->agi_freecount, 1);
                xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
-               pag = xfs_perag_get(mp, agno);
-               pag->pagi_freecount++;
-               xfs_perag_put(pag);
+               agbp->b_pag->pagi_freecount++;
                xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
        }
 
@@ -2656,7 +2643,7 @@ xfs_ialloc_read_agi(
                return error;
 
        agi = (*bpp)->b_addr;
-       pag = xfs_perag_get(mp, agno);
+       pag = (*bpp)->b_pag;
        if (!pag->pagi_init) {
                pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
                pag->pagi_count = be32_to_cpu(agi->agi_count);
@@ -2669,7 +2656,6 @@ xfs_ialloc_read_agi(
         */
        ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
                XFS_FORCED_SHUTDOWN(mp));
-       xfs_perag_put(pag);
        return 0;
 }
 
index 1eef68266969a8c78ea6e78d15c835b1991d5367..1f116b05e0830416da166712438d89959be2086d 100644 (file)
@@ -36,15 +36,13 @@ xfs_refcountbt_set_root(
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
-       struct xfs_perag        *pag = xfs_perag_get(cur->bc_mp, seqno);
+       struct xfs_perag        *pag = agbp->b_pag;
 
        ASSERT(ptr->s != 0);
 
        agf->agf_refcount_root = ptr->s;
        be32_add_cpu(&agf->agf_refcount_level, inc);
        pag->pagf_refcount_level += inc;
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(cur->bc_tp, agbp,
                        XFS_AGF_REFCOUNT_ROOT | XFS_AGF_REFCOUNT_LEVEL);
index 6d5b6a03d67b85d4b555baed7c62449137543f84..cf81e43653c11fe66e99e19d31ac51e299675787 100644 (file)
@@ -61,16 +61,14 @@ xfs_rmapbt_set_root(
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
-       xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
        int                     btnum = cur->bc_btnum;
-       struct xfs_perag        *pag = xfs_perag_get(cur->bc_mp, seqno);
+       struct xfs_perag        *pag = agbp->b_pag;
 
        ASSERT(ptr->s != 0);
 
        agf->agf_roots[btnum] = ptr->s;
        be32_add_cpu(&agf->agf_levels[btnum], inc);
        pag->pagf_levels[btnum] += inc;
-       xfs_perag_put(pag);
 
        xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
 }
@@ -121,6 +119,7 @@ xfs_rmapbt_free_block(
 {
        struct xfs_buf          *agbp = cur->bc_ag.agbp;
        struct xfs_agf          *agf = agbp->b_addr;
+       struct xfs_perag        *pag;
        xfs_agblock_t           bno;
        int                     error;
 
@@ -137,8 +136,8 @@ xfs_rmapbt_free_block(
                              XFS_EXTENT_BUSY_SKIP_DISCARD);
        xfs_trans_agbtree_delta(cur->bc_tp, -1);
 
-       xfs_ag_resv_rmapbt_free(cur->bc_mp, cur->bc_ag.agno);
-
+       pag = cur->bc_ag.agbp->b_pag;
+       xfs_ag_resv_free_extent(pag, XFS_AG_RESV_RMAPBT, NULL, 1);
        return 0;
 }