This is a port of Linux commit 048a9883267f9b8f8e05dca9e9e8e6f991eea61e: | Author: Alexey Dobriyan <adobriyan@xxxxxxxxx> | AuthorDate: Sat May 20 21:25:19 2023 +0300 | | include/linux/math.h: fix mult_frac() multiple argument evaluation bug | | mult_frac() evaluates _all_ arguments multiple times in the body. | | Clarify comment while I'm at it. | | Link: https://lkml.kernel.org/r/f9f9fdbb-ec8e-4f5e-a998-2a58627a1a43@p183 | Signed-off-by: Alexey Dobriyan <adobriyan@xxxxxxxxx> | Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- include/linux/kernel.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index c411ac0860dd..cd7dac73f93a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -107,17 +107,17 @@ extern long long simple_strtoll(const char *,char **,unsigned int); } \ ) -/* - * Multiplies an integer by a fraction, while avoiding unnecessary - * overflow or loss of precision. - */ -#define mult_frac(x, numer, denom)( \ -{ \ - typeof(x) quot = (x) / (denom); \ - typeof(x) rem = (x) % (denom); \ - (quot * (numer)) + ((rem * (numer)) / (denom)); \ -} \ -) +/* Calculate "x * n / d" without unnecessary overflow or loss of precision. */ +#define mult_frac(x, n, d) \ +({ \ + typeof(x) x_ = (x); \ + typeof(n) n_ = (n); \ + typeof(d) d_ = (d); \ + \ + typeof(x_) q = x_ / d_; \ + typeof(x_) r = x_ % d_; \ + q * n_ + r * n_ / d_; \ +}) extern const char hex_asc[]; #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] -- 2.39.2