]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: use shifting and masking when converting rt extents, if possible
authorDarrick J. Wong <djwong@kernel.org>
Mon, 16 Oct 2023 16:40:11 +0000 (09:40 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 17 Oct 2023 23:26:25 +0000 (16:26 -0700)
Avoid the costs of integer division (32-bit and 64-bit) if the realtime
extent size is a power of two.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_rtbitmap.h
fs/xfs/libxfs/xfs_sb.c
fs/xfs/xfs_linux.h
fs/xfs/xfs_mount.h
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_trans.c

index ecf5645dd67091e380cc0cd6b8f3efc0d0680f94..3686a53e0aed8bdad6412d7593411321de53bf1d 100644 (file)
@@ -11,6 +11,9 @@ xfs_rtx_to_rtb(
        struct xfs_mount        *mp,
        xfs_rtxnum_t            rtx)
 {
+       if (mp->m_rtxblklog >= 0)
+               return rtx << mp->m_rtxblklog;
+
        return rtx * mp->m_sb.sb_rextsize;
 }
 
@@ -19,6 +22,9 @@ xfs_rtxlen_to_extlen(
        struct xfs_mount        *mp,
        xfs_rtxlen_t            rtxlen)
 {
+       if (mp->m_rtxblklog >= 0)
+               return rtxlen << mp->m_rtxblklog;
+
        return rtxlen * mp->m_sb.sb_rextsize;
 }
 
@@ -28,6 +34,9 @@ xfs_extlen_to_rtxmod(
        struct xfs_mount        *mp,
        xfs_extlen_t            len)
 {
+       if (mp->m_rtxblklog >= 0)
+               return len & mp->m_rtxblkmask;
+
        return len % mp->m_sb.sb_rextsize;
 }
 
@@ -36,6 +45,9 @@ xfs_extlen_to_rtxlen(
        struct xfs_mount        *mp,
        xfs_extlen_t            len)
 {
+       if (mp->m_rtxblklog >= 0)
+               return len >> mp->m_rtxblklog;
+
        return len / mp->m_sb.sb_rextsize;
 }
 
@@ -45,6 +57,9 @@ xfs_rtb_to_rtx(
        struct xfs_mount        *mp,
        xfs_rtblock_t           rtbno)
 {
+       if (likely(mp->m_rtxblklog >= 0))
+               return rtbno >> mp->m_rtxblklog;
+
        return div_u64(rtbno, mp->m_sb.sb_rextsize);
 }
 
@@ -54,6 +69,9 @@ xfs_rtb_to_rtxoff(
        struct xfs_mount        *mp,
        xfs_rtblock_t           rtbno)
 {
+       if (likely(mp->m_rtxblklog >= 0))
+               return rtbno & mp->m_rtxblkmask;
+
        return do_div(rtbno, mp->m_sb.sb_rextsize);
 }
 
@@ -67,6 +85,11 @@ xfs_rtb_to_rtxrem(
        xfs_rtblock_t           rtbno,
        xfs_extlen_t            *off)
 {
+       if (likely(mp->m_rtxblklog >= 0)) {
+               *off = rtbno & mp->m_rtxblkmask;
+               return rtbno >> mp->m_rtxblklog;
+       }
+
        return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off);
 }
 
@@ -79,6 +102,12 @@ xfs_rtb_to_rtxup(
        struct xfs_mount        *mp,
        xfs_rtblock_t           rtbno)
 {
+       if (likely(mp->m_rtxblklog >= 0)) {
+               if (rtbno & mp->m_rtxblkmask)
+                       return (rtbno >> mp->m_rtxblklog) + 1;
+               return rtbno >> mp->m_rtxblklog;
+       }
+
        if (do_div(rtbno, mp->m_sb.sb_rextsize))
                rtbno++;
        return rtbno;
index 6264daaab37b06151bd12abc2ef9f41f61fcc675..1f74d0cd161841b410311e2490e7759e194fdfab 100644 (file)
@@ -975,6 +975,8 @@ xfs_sb_mount_common(
        mp->m_blockmask = sbp->sb_blocksize - 1;
        mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
        mp->m_blockwmask = mp->m_blockwsize - 1;
+       mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize);
+       mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize);
 
        mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
        mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
index e9d317a3dafe4e673c439e504bc7fc24ca503dbe..d7873e0360f0b9f170fc8cdaffa0ce49b1c5ed37 100644 (file)
@@ -198,6 +198,18 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y)
        return x;
 }
 
+/* If @b is a power of 2, return log2(b).  Else return -1. */
+static inline int8_t log2_if_power2(unsigned long b)
+{
+       return is_power_of_2(b) ? ilog2(b) : -1;
+}
+
+/* If @b is a power of 2, return a mask of the lower bits, else return zero. */
+static inline unsigned long long mask64_if_power2(unsigned long b)
+{
+       return is_power_of_2(b) ? b - 1 : 0;
+}
+
 int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
                char *data, enum req_op op);
 
index d19cca099bc3a701786c3e5e9871f086ac3f290c..d8769dc5f6dd717ea09e0f522214f44a33b01d94 100644 (file)
@@ -119,6 +119,7 @@ typedef struct xfs_mount {
        uint8_t                 m_blkbb_log;    /* blocklog - BBSHIFT */
        uint8_t                 m_agno_log;     /* log #ag's */
        uint8_t                 m_sectbb_log;   /* sectlog - BBSHIFT */
+       int8_t                  m_rtxblklog;    /* log2 of rextsize, if possible */
        uint                    m_blockmask;    /* sb_blocksize-1 */
        uint                    m_blockwsize;   /* sb_blocksize in words */
        uint                    m_blockwmask;   /* blockwsize-1 */
@@ -152,6 +153,7 @@ typedef struct xfs_mount {
        uint64_t                m_features;     /* active filesystem features */
        uint64_t                m_low_space[XFS_LOWSP_MAX];
        uint64_t                m_low_rtexts[XFS_LOWSP_MAX];
+       uint64_t                m_rtxblkmask;   /* rt extent block mask */
        struct xfs_ino_geometry m_ino_geo;      /* inode geometry */
        struct xfs_trans_resv   m_resv;         /* precomputed res values */
                                                /* low free space thresholds */
index ac7c269ad547581d1c1f3a2d20959e393d7ef81d..e5a3200cea72e7a4adaff18291957d40fccb52dd 100644 (file)
@@ -1054,6 +1054,7 @@ xfs_growfs_rt(
                 * Calculate new sb and mount fields for this round.
                 */
                nsbp->sb_rextsize = in->extsize;
+               nmp->m_rtxblklog = -1; /* don't use shift or masking */
                nsbp->sb_rbmblocks = bmbno + 1;
                nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize *
                                nsbp->sb_rextsize;
index 338dd37745077e99a630cbfbf4cb9f25931ab57b..305c9d07bf1b27f7c7289d746fa0f84170e60b46 100644 (file)
@@ -656,6 +656,10 @@ xfs_trans_unreserve_and_mod_sb(
        mp->m_sb.sb_agcount += tp->t_agcount_delta;
        mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
        mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
+       if (tp->t_rextsize_delta) {
+               mp->m_rtxblklog = log2_if_power2(mp->m_sb.sb_rextsize);
+               mp->m_rtxblkmask = mask64_if_power2(mp->m_sb.sb_rextsize);
+       }
        mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;
        mp->m_sb.sb_rblocks += tp->t_rblocks_delta;
        mp->m_sb.sb_rextents += tp->t_rextents_delta;