summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Maiolino <cem@kernel.org>2025-04-22 14:54:54 +0200
committerCarlos Maiolino <cem@kernel.org>2025-04-22 16:03:14 +0200
commitbd7c19331913b955a7823e6315ca16bbcc65aeff (patch)
tree2b7f1d1f724161ac2233ea25d7d3159cfba8ed42
parentc7b67ddc3c999aa2f8d77be7ef1913298fe78f0e (diff)
XFS: fix zoned gc threshold math for 32-bit arches
xfs_zoned_need_gc makes use of mult_frac() to calculate the threshold for triggering the zoned garbage collector, but, turns out mult_frac() doesn't properly work with 64-bit data types and this caused build failures on some 32-bit architectures. Fix this by essentially open coding mult_frac() in a 64-bit friendly way. Notice we don't need to bother with counters underflow here because xfs_estimate_freecounter() will always return a positive value, as it leverages percpu_counter_read_positive to read such counters. Fixes: 845abeb1f06a ("xfs: add tunable threshold parameter for triggering zone GC") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202504181233.F7D9Atra-lkp@intel.com/ Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hans Holmberg <hans.holmberg@wdc.com> Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r--fs/xfs/xfs_zone_gc.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/xfs/xfs_zone_gc.c b/fs/xfs/xfs_zone_gc.c
index 8c541ca71872..81c94dd1d596 100644
--- a/fs/xfs/xfs_zone_gc.c
+++ b/fs/xfs/xfs_zone_gc.c
@@ -170,7 +170,8 @@ bool
xfs_zoned_need_gc(
struct xfs_mount *mp)
{
- s64 available, free;
+ s64 available, free, threshold;
+ s32 remainder;
if (!xfs_group_marked(mp, XG_TYPE_RTG, XFS_RTG_RECLAIMABLE))
return false;
@@ -183,7 +184,12 @@ xfs_zoned_need_gc(
return true;
free = xfs_estimate_freecounter(mp, XC_FREE_RTEXTENTS);
- if (available < mult_frac(free, mp->m_zonegc_low_space, 100))
+
+ threshold = div_s64_rem(free, 100, &remainder);
+ threshold = threshold * mp->m_zonegc_low_space +
+ remainder * div_s64(mp->m_zonegc_low_space, 100);
+
+ if (available < threshold)
return true;
return false;