diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2023-05-20 21:25:19 +0300 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2023-06-09 17:44:22 -0700 |
commit | 048a9883267f9b8f8e05dca9e9e8e6f991eea61e (patch) | |
tree | c664cb33912840f8e3d7e852337cc3bdeab6ccc8 | |
parent | d7a0fe9ef6d6484fca4ba55c19091932337d4272 (diff) | |
download | lwn-048a9883267f9b8f8e05dca9e9e8e6f991eea61e.tar.gz lwn-048a9883267f9b8f8e05dca9e9e8e6f991eea61e.zip |
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@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r-- | include/linux/math.h | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/include/linux/math.h b/include/linux/math.h index 439b8f0b9ebd..2d388650c556 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -118,17 +118,17 @@ __STRUCT_FRACT(s32) __STRUCT_FRACT(u32) #undef __STRUCT_FRACT -/* - * 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_; \ +}) #define sector_div(a, b) do_div(a, b) |