| From: Alexey Dobriyan <adobriyan@gmail.com> |
| Subject: include/linux/math.h: fix mult_frac() multiple argument evaluation bug |
| Date: Sat, 20 May 2023 21:25:19 +0300 |
| |
| 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> |
| --- |
| |
| include/linux/math.h | 22 +++++++++++----------- |
| 1 file changed, 11 insertions(+), 11 deletions(-) |
| |
| --- a/include/linux/math.h~fix-mult_frac-multiple-argument-evaluation-bug |
| +++ a/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) |
| |
| _ |