diff mbox series

[net-next] ice: add and use roundup_u64 instead of open coding equivalent

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

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 15215 this patch: 15215
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 2091 this patch: 2091
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 16382 this patch: 16382
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 48 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 64 this patch: 64
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-05-10--06-00 (tests: 1010)

Commit Message

Tony Nguyen May 7, 2024, 8:54 p.m. UTC
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>
---
 drivers/net/ethernet/intel/ice/ice_ptp.c |  3 +--
 include/linux/math64.h                   | 29 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

Comments

Simon Horman May 8, 2024, 8:22 p.m. UTC | #1
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>

...
Jakub Kicinski May 11, 2024, 1:13 a.m. UTC | #2
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 mbox series

Patch

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 */