Skip to content

Commit ef5a83b

Browse files
author
Darrick J. Wong
committed
xfs: use shifting and masking when converting rt extents, if possible
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>
1 parent 5f57f73 commit ef5a83b

File tree

6 files changed

+50
-0
lines changed

6 files changed

+50
-0
lines changed

fs/xfs/libxfs/xfs_rtbitmap.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ xfs_rtx_to_rtb(
1111
struct xfs_mount *mp,
1212
xfs_rtxnum_t rtx)
1313
{
14+
if (mp->m_rtxblklog >= 0)
15+
return rtx << mp->m_rtxblklog;
16+
1417
return rtx * mp->m_sb.sb_rextsize;
1518
}
1619

@@ -19,6 +22,9 @@ xfs_rtxlen_to_extlen(
1922
struct xfs_mount *mp,
2023
xfs_rtxlen_t rtxlen)
2124
{
25+
if (mp->m_rtxblklog >= 0)
26+
return rtxlen << mp->m_rtxblklog;
27+
2228
return rtxlen * mp->m_sb.sb_rextsize;
2329
}
2430

@@ -28,6 +34,9 @@ xfs_extlen_to_rtxmod(
2834
struct xfs_mount *mp,
2935
xfs_extlen_t len)
3036
{
37+
if (mp->m_rtxblklog >= 0)
38+
return len & mp->m_rtxblkmask;
39+
3140
return len % mp->m_sb.sb_rextsize;
3241
}
3342

@@ -36,6 +45,9 @@ xfs_extlen_to_rtxlen(
3645
struct xfs_mount *mp,
3746
xfs_extlen_t len)
3847
{
48+
if (mp->m_rtxblklog >= 0)
49+
return len >> mp->m_rtxblklog;
50+
3951
return len / mp->m_sb.sb_rextsize;
4052
}
4153

@@ -45,6 +57,9 @@ xfs_rtb_to_rtx(
4557
struct xfs_mount *mp,
4658
xfs_rtblock_t rtbno)
4759
{
60+
if (likely(mp->m_rtxblklog >= 0))
61+
return rtbno >> mp->m_rtxblklog;
62+
4863
return div_u64(rtbno, mp->m_sb.sb_rextsize);
4964
}
5065

@@ -54,6 +69,9 @@ xfs_rtb_to_rtxoff(
5469
struct xfs_mount *mp,
5570
xfs_rtblock_t rtbno)
5671
{
72+
if (likely(mp->m_rtxblklog >= 0))
73+
return rtbno & mp->m_rtxblkmask;
74+
5775
return do_div(rtbno, mp->m_sb.sb_rextsize);
5876
}
5977

@@ -67,6 +85,11 @@ xfs_rtb_to_rtxrem(
6785
xfs_rtblock_t rtbno,
6886
xfs_extlen_t *off)
6987
{
88+
if (likely(mp->m_rtxblklog >= 0)) {
89+
*off = rtbno & mp->m_rtxblkmask;
90+
return rtbno >> mp->m_rtxblklog;
91+
}
92+
7093
return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off);
7194
}
7295

@@ -79,6 +102,12 @@ xfs_rtb_to_rtxup(
79102
struct xfs_mount *mp,
80103
xfs_rtblock_t rtbno)
81104
{
105+
if (likely(mp->m_rtxblklog >= 0)) {
106+
if (rtbno & mp->m_rtxblkmask)
107+
return (rtbno >> mp->m_rtxblklog) + 1;
108+
return rtbno >> mp->m_rtxblklog;
109+
}
110+
82111
if (do_div(rtbno, mp->m_sb.sb_rextsize))
83112
rtbno++;
84113
return rtbno;

fs/xfs/libxfs/xfs_sb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,8 @@ xfs_sb_mount_common(
975975
mp->m_blockmask = sbp->sb_blocksize - 1;
976976
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
977977
mp->m_blockwmask = mp->m_blockwsize - 1;
978+
mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize);
979+
mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize);
978980

979981
mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
980982
mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);

fs/xfs/xfs_linux.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y)
198198
return x;
199199
}
200200

201+
/* If @b is a power of 2, return log2(b). Else return -1. */
202+
static inline int8_t log2_if_power2(unsigned long b)
203+
{
204+
return is_power_of_2(b) ? ilog2(b) : -1;
205+
}
206+
207+
/* If @b is a power of 2, return a mask of the lower bits, else return zero. */
208+
static inline unsigned long long mask64_if_power2(unsigned long b)
209+
{
210+
return is_power_of_2(b) ? b - 1 : 0;
211+
}
212+
201213
int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count,
202214
char *data, enum req_op op);
203215

fs/xfs/xfs_mount.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ typedef struct xfs_mount {
119119
uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
120120
uint8_t m_agno_log; /* log #ag's */
121121
uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
122+
int8_t m_rtxblklog; /* log2 of rextsize, if possible */
122123
uint m_blockmask; /* sb_blocksize-1 */
123124
uint m_blockwsize; /* sb_blocksize in words */
124125
uint m_blockwmask; /* blockwsize-1 */
@@ -152,6 +153,7 @@ typedef struct xfs_mount {
152153
uint64_t m_features; /* active filesystem features */
153154
uint64_t m_low_space[XFS_LOWSP_MAX];
154155
uint64_t m_low_rtexts[XFS_LOWSP_MAX];
156+
uint64_t m_rtxblkmask; /* rt extent block mask */
155157
struct xfs_ino_geometry m_ino_geo; /* inode geometry */
156158
struct xfs_trans_resv m_resv; /* precomputed res values */
157159
/* low free space thresholds */

fs/xfs/xfs_rtalloc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,7 @@ xfs_growfs_rt(
10541054
* Calculate new sb and mount fields for this round.
10551055
*/
10561056
nsbp->sb_rextsize = in->extsize;
1057+
nmp->m_rtxblklog = -1; /* don't use shift or masking */
10571058
nsbp->sb_rbmblocks = bmbno + 1;
10581059
nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize *
10591060
nsbp->sb_rextsize;

fs/xfs/xfs_trans.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,10 @@ xfs_trans_unreserve_and_mod_sb(
656656
mp->m_sb.sb_agcount += tp->t_agcount_delta;
657657
mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
658658
mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
659+
if (tp->t_rextsize_delta) {
660+
mp->m_rtxblklog = log2_if_power2(mp->m_sb.sb_rextsize);
661+
mp->m_rtxblkmask = mask64_if_power2(mp->m_sb.sb_rextsize);
662+
}
659663
mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;
660664
mp->m_sb.sb_rblocks += tp->t_rblocks_delta;
661665
mp->m_sb.sb_rextents += tp->t_rextents_delta;

0 commit comments

Comments
 (0)