Message ID | 20240507205441.1657884-1-anthony.l.nguyen@intel.com (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] ice: add and use roundup_u64 instead of open coding equivalent | expand |
On Tue, May 07, 2024 at 01:54:39PM -0700, Tony Nguyen wrote: > From: Jacob Keller <jacob.e.keller@intel.com> > > In ice_ptp_cfg_clkout(), the ice driver needs to calculate the nearest next > second of a current time value specified in nanoseconds. It implements this > using div64_u64, because the time value is a u64. It could use div_u64 > since NSEC_PER_SEC is smaller than 32-bits. > > Ideally this would be implemented directly with roundup(), but that can't > work on all platforms due to a division which requires using the specific > macros and functions due to platform restrictions, and to ensure that the > most appropriate and fast instructions are used. > > The kernel doesn't currently provide any 64-bit equivalents for doing > roundup. Attempting to use roundup() on a 32-bit platform will result in a > link failure due to not having a direct 64-bit division. > > The closest equivalent for this is DIV64_U64_ROUND_UP, which does a > division always rounding up. However, this only computes the division, and > forces use of the div64_u64 in cases where the divisor is a 32bit value and > could make use of div_u64. > > Introduce DIV_U64_ROUND_UP based on div_u64, and then use it to implement > roundup_u64 which takes a u64 input value and a u32 rounding value. > > The name roundup_u64 matches the naming scheme of div_u64, and future > patches could implement roundup64_u64 if they need to round by a multiple > that is greater than 32-bits. > > Replace the logic in ice_ptp.c which does this equivalent with the newly > added roundup_u64. > > Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> > Tested-by: Arpana Arland <arpanax.arland@intel.com> (A Contingent worker at Intel) > Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> ...
On Tue, 7 May 2024 13:54:39 -0700 Tony Nguyen wrote: > + * @y: 32bit multiple to round up to > + * @y: multiple to round up to @y kdoc got duplicated
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 0f17fc1181d2..a95af8d638a0 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -1714,8 +1714,7 @@ static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan, * maintaining phase */ if (start_time < current_time) - start_time = div64_u64(current_time + NSEC_PER_SEC - 1, - NSEC_PER_SEC) * NSEC_PER_SEC + phase; + start_time = roundup_u64(current_time, NSEC_PER_SEC) + phase; if (ice_is_e810(hw)) start_time -= E810_OUT_PROP_DELAY_NS; diff --git a/include/linux/math64.h b/include/linux/math64.h index bf74478926d4..553043ebf4cc 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -301,6 +301,19 @@ u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div); #define DIV64_U64_ROUND_UP(ll, d) \ ({ u64 _tmp = (d); div64_u64((ll) + _tmp - 1, _tmp); }) +/** + * DIV_U64_ROUND_UP - unsigned 64bit divide with 32bit divisor rounded up + * @ll: unsigned 64bit dividend + * @d: unsigned 32bit divisor + * + * Divide unsigned 64bit dividend by unsigned 32bit divisor + * and round up. + * + * Return: dividend / divisor rounded up + */ +#define DIV_U64_ROUND_UP(ll, d) \ + ({ u32 _tmp = (d); div_u64((ll) + _tmp - 1, _tmp); }) + /** * DIV64_U64_ROUND_CLOSEST - unsigned 64bit divide with 64bit divisor rounded to nearest integer * @dividend: unsigned 64bit dividend @@ -346,4 +359,20 @@ u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div); div_s64((__x - (__d / 2)), __d); \ } \ ) + +/** + * roundup_u64 - Round up a 64bit value to the next specified 32bit multiple + * @x: the value to up + * @y: 32bit multiple to round up to + * @y: multiple to round up to + * + * Rounds @x to the next multiple of @y. For 32bit @x values, see roundup and + * the faster round_up() for powers of 2. + * + * Return: rounded up value + */ +static inline u64 roundup_u64(u64 x, u32 y) +{ + return DIV_U64_ROUND_UP(x, y) * y; +} #endif /* _LINUX_MATH64_H */