]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: use shifting and masking when converting rt extents, if possible
authorDarrick J. Wong <djwong@kernel.org>
Mon, 12 Feb 2024 14:24:20 +0000 (15:24 +0100)
committerCarlos Maiolino <cem@kernel.org>
Thu, 15 Feb 2024 11:56:43 +0000 (12:56 +0100)
Source kernel commit: ef5a83b7e597038d1c734ddb4bc00638082c2bf1

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>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
include/xfs_mount.h
libxfs/libxfs_priv.h
libxfs/xfs_rtbitmap.h
libxfs/xfs_sb.c

index 9adc1f89867ccdfd339311de7a46dc493c526e27..98d5b199de8c43f3780ec7a61812dbc04255bc44 100644 (file)
@@ -71,6 +71,7 @@ typedef struct xfs_mount {
        uint8_t                 m_blkbb_log;    /* blocklog - BBSHIFT */
        uint8_t                 m_sectbb_log;   /* sectorlog - BBSHIFT */
        uint8_t                 m_agno_log;     /* log #ag's */
+       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 */
@@ -93,6 +94,7 @@ typedef struct xfs_mount {
        struct radix_tree_root  m_perag_tree;
        uint64_t                m_features;     /* active filesystem features */
        uint64_t                m_low_space[XFS_LOWSP_MAX];
+       uint64_t                m_rtxblkmask;   /* rt extent block mask */
        unsigned long           m_opstate;      /* dynamic state flags */
        bool                    m_finobt_nores; /* no per-AG finobt resv. */
        uint                    m_qflags;       /* quota status flags */
index ed437e38e9dab9a098a32ee1586e883cac03a14a..30ff8dba9178c3c16f8777eaa2b4888647ca4ae5 100644 (file)
@@ -323,6 +323,30 @@ roundup_pow_of_two(uint v)
        return 0;
 }
 
+/* If @b is a power of 2, return log2(b).  Else return -1. */
+static inline int8_t log2_if_power2(unsigned long b)
+{
+       unsigned long   mask = 1;
+       unsigned int    i;
+       unsigned int    ret = 1;
+
+       if (!is_power_of_2(b))
+               return -1;
+
+       for (i = 0; i < NBBY * sizeof(unsigned long); i++, mask <<= 1) {
+               if (b & mask)
+                       ret = i;
+       }
+
+       return ret;
+}
+
+/* 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;
+}
+
 /* buffer management */
 #define XBF_TRYLOCK                    0
 #define XBF_UNMAPPED                   0
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 01935017cb6ed5f7f7be837dcd45568a8e7868c7..1ebdb7ec41f4d4d3f078e4e59f91e13d5307ac4d 100644 (file)
@@ -973,6 +973,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);