[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4rp80297-985r-546o-on47-q34rr7po03r7@syhkavp.arg>
Date: Sat, 14 Jun 2025 11:17:33 -0400 (EDT)
From: Nicolas Pitre <nico@...xnic.net>
To: David Laight <david.laight.linux@...il.com>
cc: Andrew Morton <akpm@...ux-foundation.org>, linux-kernel@...r.kernel.org,
u.kleine-koenig@...libre.com, Oleg Nesterov <oleg@...hat.com>,
Peter Zijlstra <peterz@...radead.org>,
Biju Das <biju.das.jz@...renesas.com>, Nicolas Pitre <npitre@...libre.com>
Subject: Re: [PATCH v3 next 02/10] lib: mul_u64_u64_div_u64() Use WARN_ONCE()
for divide errors.
On Sat, 14 Jun 2025, David Laight wrote:
> Do an explicit WARN_ONCE(!divisor) instead of hoping the 'undefined
> behaviour' the compiler generates for a compile-time 1/0 is in any
> way useful.
>
> Return 0 (rather than ~(u64)0) because it is less likely to cause
> further serious issues.
I still disagree with this patch. Whether or not what the compiler
produces is useful is beside the point. What's important here is to have
a coherent behavior across all division flavors and what's proposed here
is not.
Arguably, a compile time 1/0 might not be what we want either. The
compiler forces an "illegal instruction" exception when what we want is
a "floating point" exception (strange to have floating point exceptions
for integer divisions but that's what it is).
So I'd suggest the following instead:
----- >8
>From Nicolas Pitre <npitre@...libre.com>
Subject: [PATCH] mul_u64_u64_div_u64(): improve division-by-zero handling
Forcing 1/0 at compile time makes the compiler (on x86 at least) to emit
an undefined instruction to trigger the exception. But that's not what
we want. Modify the code so that an actual runtime div-by-0 exception
is triggered to be coherent with the behavior of all the other division
flavors.
And don't use 1 for the dividend as the compiler would convert the
actual division into a simple compare.
Signed-off-by: Nicolas Pitre <npitre@...libre.com>
diff --git a/lib/math/div64.c b/lib/math/div64.c
index 5faa29208bdb..e6839b40e271 100644
--- a/lib/math/div64.c
+++ b/lib/math/div64.c
@@ -212,12 +212,12 @@ u64 mul_u64_u64_div_u64(u64 a, u64 b, u64 c)
#endif
- /* make sure c is not zero, trigger exception otherwise */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdiv-by-zero"
- if (unlikely(c == 0))
- return 1/0;
-#pragma GCC diagnostic pop
+ /* make sure c is not zero, trigger runtime exception otherwise */
+ if (unlikely(c == 0)) {
+ unsigned long zero = 0;
+ asm ("" : "+r" (zero)); /* hide actual value from the compiler */
+ return ~0UL/zero;
+ }
int shift = __builtin_ctzll(c);
Powered by blists - more mailing lists