[PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()

Cristian Ciocaltea posted 4 patches 1 week, 6 days ago
There is a newer version of this series
[PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()
Posted by Cristian Ciocaltea 1 week, 6 days ago
Currently DIV_ROUND_CLOSEST() is only available for the kernel via
include/linux/math.h.

Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
a common definition in uapi.

Additionally, ensure it allows building ISO C applications by switching
from the 'typeof' GNU extension to the ISO-friendly __typeof__.

Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Tested-by: Diederik de Haas <diederik@cknow-tech.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 include/linux/math.h       | 18 +-----------------
 include/uapi/linux/const.h | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/include/linux/math.h b/include/linux/math.h
index 6dc1d1d32fbc..1e8fb3efbc8c 100644
--- a/include/linux/math.h
+++ b/include/linux/math.h
@@ -89,23 +89,7 @@
 }							\
 )
 
-/*
- * Divide positive or negative dividend by positive or negative divisor
- * and round to closest integer. Result is undefined for negative
- * divisors if the dividend variable type is unsigned and for negative
- * dividends if the divisor variable type is unsigned.
- */
-#define DIV_ROUND_CLOSEST(x, divisor)(			\
-{							\
-	typeof(x) __x = x;				\
-	typeof(divisor) __d = divisor;			\
-	(((typeof(x))-1) > 0 ||				\
-	 ((typeof(divisor))-1) > 0 ||			\
-	 (((__x) > 0) == ((__d) > 0))) ?		\
-		(((__x) + ((__d) / 2)) / (__d)) :	\
-		(((__x) - ((__d) / 2)) / (__d));	\
-}							\
-)
+#define DIV_ROUND_CLOSEST __KERNEL_DIV_ROUND_CLOSEST
 /*
  * Same as above but for u64 dividends. divisor must be a 32-bit
  * number.
diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h
index b8f629ef135f..471877322f47 100644
--- a/include/uapi/linux/const.h
+++ b/include/uapi/linux/const.h
@@ -50,4 +50,21 @@
 
 #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
 
+/*
+ * Divide positive or negative dividend by positive or negative divisor
+ * and round to closest integer. Result is undefined for negative
+ * divisors if the dividend variable type is unsigned and for negative
+ * dividends if the divisor variable type is unsigned.
+ */
+#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor)(		\
+{							\
+	__typeof__(x) __x = x;				\
+	__typeof__(divisor) __d = divisor;		\
+	(((__typeof__(x))-1) > 0 ||			\
+	 ((__typeof__(divisor))-1) > 0 ||		\
+	 (((__x) > 0) == ((__d) > 0))) ?		\
+		(((__x) + ((__d) / 2)) / (__d)) :	\
+		(((__x) - ((__d) / 2)) / (__d));	\
+}							\
+)
 #endif /* _UAPI_LINUX_CONST_H */

-- 
2.52.0

Re: [PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()
Posted by Jani Nikula 1 week, 6 days ago
On Tue, 27 Jan 2026, Cristian Ciocaltea <cristian.ciocaltea@collabora.com> wrote:
> Currently DIV_ROUND_CLOSEST() is only available for the kernel via
> include/linux/math.h.
>
> Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
> a common definition in uapi.
>
> Additionally, ensure it allows building ISO C applications by switching
> from the 'typeof' GNU extension to the ISO-friendly __typeof__.

I am not convinced that it's a good idea to make the implementation of
kernel DIV_ROUND_CLOSEST() part of the kernel UAPI, which is what this
change effectively does.

I'd at least like to get an ack from Andy Shevchenko first (Cc'd).


BR,
Jani.

> Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
>  include/linux/math.h       | 18 +-----------------
>  include/uapi/linux/const.h | 17 +++++++++++++++++
>  2 files changed, 18 insertions(+), 17 deletions(-)
>
> diff --git a/include/linux/math.h b/include/linux/math.h
> index 6dc1d1d32fbc..1e8fb3efbc8c 100644
> --- a/include/linux/math.h
> +++ b/include/linux/math.h
> @@ -89,23 +89,7 @@
>  }							\
>  )
>  
> -/*
> - * Divide positive or negative dividend by positive or negative divisor
> - * and round to closest integer. Result is undefined for negative
> - * divisors if the dividend variable type is unsigned and for negative
> - * dividends if the divisor variable type is unsigned.
> - */
> -#define DIV_ROUND_CLOSEST(x, divisor)(			\
> -{							\
> -	typeof(x) __x = x;				\
> -	typeof(divisor) __d = divisor;			\
> -	(((typeof(x))-1) > 0 ||				\
> -	 ((typeof(divisor))-1) > 0 ||			\
> -	 (((__x) > 0) == ((__d) > 0))) ?		\
> -		(((__x) + ((__d) / 2)) / (__d)) :	\
> -		(((__x) - ((__d) / 2)) / (__d));	\
> -}							\
> -)
> +#define DIV_ROUND_CLOSEST __KERNEL_DIV_ROUND_CLOSEST
>  /*
>   * Same as above but for u64 dividends. divisor must be a 32-bit
>   * number.
> diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h
> index b8f629ef135f..471877322f47 100644
> --- a/include/uapi/linux/const.h
> +++ b/include/uapi/linux/const.h
> @@ -50,4 +50,21 @@
>  
>  #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
>  
> +/*
> + * Divide positive or negative dividend by positive or negative divisor
> + * and round to closest integer. Result is undefined for negative
> + * divisors if the dividend variable type is unsigned and for negative
> + * dividends if the divisor variable type is unsigned.
> + */
> +#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor)(		\
> +{							\
> +	__typeof__(x) __x = x;				\
> +	__typeof__(divisor) __d = divisor;		\
> +	(((__typeof__(x))-1) > 0 ||			\
> +	 ((__typeof__(divisor))-1) > 0 ||		\
> +	 (((__x) > 0) == ((__d) > 0))) ?		\
> +		(((__x) + ((__d) / 2)) / (__d)) :	\
> +		(((__x) - ((__d) / 2)) / (__d));	\
> +}							\
> +)
>  #endif /* _UAPI_LINUX_CONST_H */

-- 
Jani Nikula, Intel
Re: [PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()
Posted by Andy Shevchenko 1 week, 6 days ago
On Tue, Jan 27, 2026 at 03:58:13PM +0200, Jani Nikula wrote:
> On Tue, 27 Jan 2026, Cristian Ciocaltea <cristian.ciocaltea@collabora.com> wrote:
> > Currently DIV_ROUND_CLOSEST() is only available for the kernel via
> > include/linux/math.h.
> >
> > Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
> > a common definition in uapi.
> >
> > Additionally, ensure it allows building ISO C applications by switching
> > from the 'typeof' GNU extension to the ISO-friendly __typeof__.
> 
> I am not convinced that it's a good idea to make the implementation of
> kernel DIV_ROUND_CLOSEST() part of the kernel UAPI, which is what this
> change effectively does.
> 
> I'd at least like to get an ack from Andy Shevchenko first (Cc'd).

Thanks for Cc'ing me!

So, the history of the DIV_ROUND_UP() to appear in UAPI is a response to
the ethtool change that missed the fact that this was a kernel internal macro.
Giving a precedent there is no technical issues to add DIV_ROUND_CLOSEST()
to UAPI as proposed. Main question here is: Does DRM headers in question
(that are going to use it) really need this?

Interestingly that DRM also started using __KERNEL_DIV_ROUND_UP() in UAPI
at some point, which kinda makes an argument for allowing the other one.

Also fun fact: this series plead for a new macro for division while ignoring
existing (UAPI) macros for masks and bits.

0xffffU is effectively __GENMASK(15, 0). (And if you change the code, avoid
using variables inside GENMASK() macros, it may generate an awful code, the
GENMASK($HI, $LO) << foo is preferred over GENMASK(foo + $DELTA, foo) case.
GENMASK(foo - 1, 0) OTOH is fine, however be always careful against overflows
with left shifts, as BIT(foo) - 1 may not work for foo == 32, while GENMASK()
may not work for foo == 0).

So, I have no objections for either choice
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

...

But if you go that direction, please, fix up the style.

> > +/*
> > + * Divide positive or negative dividend by positive or negative divisor
> > + * and round to closest integer. Result is undefined for negative
> > + * divisors if the dividend variable type is unsigned and for negative
> > + * dividends if the divisor variable type is unsigned.
> > + */
> > +#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor)(		\
> > +{							\

Use ({ on this line together...

> > +	__typeof__(x) __x = x;				\
> > +	__typeof__(divisor) __d = divisor;		\

+ blank line here.

> > +	(((__typeof__(x))-1) > 0 ||			\
> > +	 ((__typeof__(divisor))-1) > 0 ||		\
> > +	 (((__x) > 0) == ((__d) > 0))) ?		\
> > +		(((__x) + ((__d) / 2)) / (__d)) :	\
> > +		(((__x) - ((__d) / 2)) / (__d));	\
> > +}							\
> > +)

...as here join }) to be a single line.

+ blank line.

> >  #endif /* _UAPI_LINUX_CONST_H */

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()
Posted by Cristian Ciocaltea 1 week, 5 days ago
Hi Andy,

On 1/27/26 4:38 PM, Andy Shevchenko wrote:
> On Tue, Jan 27, 2026 at 03:58:13PM +0200, Jani Nikula wrote:
>> On Tue, 27 Jan 2026, Cristian Ciocaltea <cristian.ciocaltea@collabora.com> wrote:
>>> Currently DIV_ROUND_CLOSEST() is only available for the kernel via
>>> include/linux/math.h.
>>>
>>> Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
>>> a common definition in uapi.
>>>
>>> Additionally, ensure it allows building ISO C applications by switching
>>> from the 'typeof' GNU extension to the ISO-friendly __typeof__.
>>
>> I am not convinced that it's a good idea to make the implementation of
>> kernel DIV_ROUND_CLOSEST() part of the kernel UAPI, which is what this
>> change effectively does.
>>
>> I'd at least like to get an ack from Andy Shevchenko first (Cc'd).
> 
> Thanks for Cc'ing me!
> 
> So, the history of the DIV_ROUND_UP() to appear in UAPI is a response to
> the ethtool change that missed the fact that this was a kernel internal macro.
> Giving a precedent there is no technical issues to add DIV_ROUND_CLOSEST()
> to UAPI as proposed. Main question here is: Does DRM headers in question
> (that are going to use it) really need this?
> 
> Interestingly that DRM also started using __KERNEL_DIV_ROUND_UP() in UAPI
> at some point, which kinda makes an argument for allowing the other one.
> 
> Also fun fact: this series plead for a new macro for division while ignoring
> existing (UAPI) macros for masks and bits.

Yeah, I initially planned to make use of those, but gave up after realizing the
FIELD_{PREP|GET} were not exposed. I reconsidered my position now that you
mentioned it. :-)

> 
> 0xffffU is effectively __GENMASK(15, 0). (And if you change the code, avoid
> using variables inside GENMASK() macros, it may generate an awful code, the
> GENMASK($HI, $LO) << foo is preferred over GENMASK(foo + $DELTA, foo) case.
> GENMASK(foo - 1, 0) OTOH is fine, however be always careful against overflows
> with left shifts, as BIT(foo) - 1 may not work for foo == 32, while GENMASK()
> may not work for foo == 0).

Thanks for the heads up!

> 
> So, I have no objections for either choice
> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> 
> ...
> 
> But if you go that direction, please, fix up the style.
> 
>>> +/*
>>> + * Divide positive or negative dividend by positive or negative divisor
>>> + * and round to closest integer. Result is undefined for negative
>>> + * divisors if the dividend variable type is unsigned and for negative
>>> + * dividends if the divisor variable type is unsigned.
>>> + */
>>> +#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor)(		\
>>> +{							\
> 
> Use ({ on this line together...
> 
>>> +	__typeof__(x) __x = x;				\
>>> +	__typeof__(divisor) __d = divisor;		\
> 
> + blank line here.
> 
>>> +	(((__typeof__(x))-1) > 0 ||			\
>>> +	 ((__typeof__(divisor))-1) > 0 ||		\
>>> +	 (((__x) > 0) == ((__d) > 0))) ?		\
>>> +		(((__x) + ((__d) / 2)) / (__d)) :	\
>>> +		(((__x) - ((__d) / 2)) / (__d));	\
>>> +}							\
>>> +)
> 
> ...as here join }) to be a single line.
> 
> + blank line.
> 
>>>  #endif /* _UAPI_LINUX_CONST_H */


Thanks for the review! I've addressed all your comments (hopefully) in v6:

https://lore.kernel.org/all/20260129-rk3588-bgcolor-v6-0-c15f755a4055@collabora.com/

Regards,
Cristian
Re: [PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()
Posted by David Laight 1 week, 6 days ago
On Tue, 27 Jan 2026 16:38:00 +0200
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:

> On Tue, Jan 27, 2026 at 03:58:13PM +0200, Jani Nikula wrote:
> > On Tue, 27 Jan 2026, Cristian Ciocaltea <cristian.ciocaltea@collabora.com> wrote:  
> > > Currently DIV_ROUND_CLOSEST() is only available for the kernel via
> > > include/linux/math.h.
> > >
> > > Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
> > > a common definition in uapi.
> > >
> > > Additionally, ensure it allows building ISO C applications by switching
> > > from the 'typeof' GNU extension to the ISO-friendly __typeof__.  
> > 
> > I am not convinced that it's a good idea to make the implementation of
> > kernel DIV_ROUND_CLOSEST() part of the kernel UAPI, which is what this
> > change effectively does.
> > 
> > I'd at least like to get an ack from Andy Shevchenko first (Cc'd).  
> 
> Thanks for Cc'ing me!
> 
> So, the history of the DIV_ROUND_UP() to appear in UAPI is a response to
> the ethtool change that missed the fact that this was a kernel internal macro.
> Giving a precedent there is no technical issues to add DIV_ROUND_CLOSEST()
> to UAPI as proposed. Main question here is: Does DRM headers in question
> (that are going to use it) really need this?

My 2c...

And is it actually going to 'clean compile' in userspace?
The tests for x < 0 are very likely to generate warnings when x
is unsigned.
It is hard to avoid those in the kernel build, never mind some 'random'
userspace build.

I'd have thought that the only reason for any of the kernel defines 'leaking'
into the uapi headers is that they are used in other uapi headers for
constants that programs need to use.

It isn't as though it isn't hard to write something that will 'do the job'
and in a place where the definition will be found while reading the sources.
Even just 'hiding' the definitions the kernel itself uses in the uapi
headers doesn't really help anyone.

	David
Re: [PATCH v5 1/4] uapi: Provide DIV_ROUND_CLOSEST()
Posted by AngeloGioacchino Del Regno 1 week, 6 days ago
Il 27/01/26 09:45, Cristian Ciocaltea ha scritto:
> Currently DIV_ROUND_CLOSEST() is only available for the kernel via
> include/linux/math.h.
> 
> Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
> a common definition in uapi.
> 
> Additionally, ensure it allows building ISO C applications by switching
> from the 'typeof' GNU extension to the ISO-friendly __typeof__.
> 
> Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>