From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753353AbbIPM6I (ORCPT ); Wed, 16 Sep 2015 08:58:08 -0400 Received: from mail-wi0-f181.google.com ([209.85.212.181]:38052 "EHLO mail-wi0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752226AbbIPM6C convert rfc822-to-8bit (ORCPT ); Wed, 16 Sep 2015 08:58:02 -0400 From: Michal Nazarewicz To: Linus Torvalds , Ingo Molnar Cc: John Stultz , LKML , Andrew Morton , "Steven Rostedt \(Red Hat\)" , Peter Zijlstra , Masami Hiramatsu , Peter Zijlstra Subject: [PATCH] kernel.h: make abs() work with 64-bit types In-Reply-To: Organization: http://mina86.com/ References: <1442279124-7309-1-git-send-email-john.stultz@linaro.org> <1442279124-7309-6-git-send-email-john.stultz@linaro.org> <20150915052202.GB14215@gmail.com> User-Agent: Notmuch/0.19+53~g2e63a09 (http://notmuchmail.org) Emacs/25.0.50.1 (x86_64-unknown-linux-gnu) X-Face: PbkBB1w#)bOqd`iCe"Ds{e+!C7`pkC9a|f)Qo^BMQvy\q5x3?vDQJeN(DS?|-^$uMti[3D*#^_Ts"pU$jBQLq~Ud6iNwAw_r_o_4]|JO?]}P_}Nc&"p#D(ZgUb4uCNPe7~a[DbPG0T~!&c.y$Ur,=N4RT>]dNpd;KFrfMCylc}gc??'U2j,!8%xdD Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAJFBMVEWbfGlUPDDHgE57V0jUupKjgIObY0PLrom9mH4dFRK4gmjPs41MxjOgAAACQElEQVQ4jW3TMWvbQBQHcBk1xE6WyALX1069oZBMlq+ouUwpEQQ6uRjttkWP4CmBgGM0BQLBdPFZYPsyFUo6uEtKDQ7oy/U96XR2Ux8ehH/89Z6enqxBcS7Lg81jmSuujrfCZcLI/TYYvbGj+jbgFpHJ/bqQAUISj8iLyu4LuFHJTosxsucO4jSDNE0Hq3hwK/ceQ5sx97b8LcUDsILfk+ovHkOIsMbBfg43VuQ5Ln9YAGCkUdKJoXR9EclFBhixy3EGVz1K6eEkhxCAkeMMnqoAhAKwhoUJkDrCqvbecaYINlFKSRS1i12VKH1XpUd4qxL876EkMcDvHj3s5RBajHHMlA5iK32e0C7VgG0RlzFPvoYHZLRmAC0BmNcBruhkE0KsMsbEc62ZwUJDxWUdMsMhVqovoT96i/DnX/ASvz/6hbCabELLk/6FF/8PNpPCGqcZTGFcBhhAaZZDbQPaAB3+KrWWy2XgbYDNIinkdWAFcCpraDE/knwe5DBqGmgzESl1p2E4MWAz0VUPgYYzmfWb9yS4vCvgsxJriNTHoIBz5YteBvg+VGISQWUqhMiByPIPpygeDBE6elD973xWwKkEiHZAHKjhuPsFnBuArrzxtakRcISv+XMIPl4aGBUJm8Emk7qBYU8IlgNEIpiJhk/No24jHwkKTFHDWfPniR4iw5vJaw2nzSjfq2zffcE/GDjRC2dn0J0XwPAbDL84TvaFCJEU4Oml9pRyEUhR3Cl2t01AoEjRbs0sYugp14/4X5n4pU4EHHnMAAAAAElFTkSuQmCC X-PGP: 50751FF4 X-PGP-FP: AC1F 5F5C D418 88F8 CC84 5858 2060 4012 5075 1FF4 X-Hashcash: 1:20:150916:mingo@kernel.org::zono2yW+yaV5PmbI:00kRd X-Hashcash: 1:20:150916:linux-kernel@vger.kernel.org::CpL0g+haUiemW2l5:0000000000000000000000000000000000ptG X-Hashcash: 1:20:150916:akpm@linux-foundation.org::Oc2kTYrZ0SYcemjS:0000000000000000000000000000000000001ATi X-Hashcash: 1:20:150916:a.p.zijlstra@chello.nl::ecpVNIBqDsC/abjQ:0000000000000000000000000000000000000000mrB X-Hashcash: 1:20:150916:rostedt@goodmis.org::1exRJG5+Tnp/uRLD:0000000000000000000000000000000000000000002rvX X-Hashcash: 1:20:150916:peterz@infradead.org::0h5Ygvz1hJ2gyFJG:000000000000000000000000000000000000000003/h0 X-Hashcash: 1:20:150916:john.stultz@linaro.org::fl8VxY0AScSaGFUO:0000000000000000000000000000000000000003OHV X-Hashcash: 1:20:150916:torvalds@linux-foundation.org::MCFdkt1qMVfgldfN:000000000000000000000000000000009ADf X-Hashcash: 1:20:150916:masami.hiramatsu.pt@hitachi.com::+7+2hvP/V5SJkpY0:00000000000000000000000000000098nx Date: Wed, 16 Sep 2015 14:57:59 +0200 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For 64-bit arguments, abs macro casts it to an int which leads to lost precision and may cause incorrect results. To deal with 64-bit types abs64 macro has been introduced but still there are places where abs macro is used incorrectly. To deal with the problem, expand abs macro such that it operates on s64 type when dealing with 64-bit types while still returning long when dealing with smaller types. Signed-off-by: Michal Nazarewicz --- include/linux/kernel.h | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) On Tue, Sep 15 2015, Linus Torvalds wrote: > So I think the "auto-expand to 's64' using __builtin_choose_expr()" is > the preferable model, and get rid of abs64() entirely. It has very few > uses. Compile tested (with ‘make allmodconfig && make bzImage modules’ on x86_64) only. The 32-bit case could be further ‘simplified’ with: typeof(__builtin_choose_expr(sizeof(x) == sizeof(long), \ 1L, 1)) __x = (x); \ (long)(__x < 0 ? -__x : __x); but I don’t suppose the few saved lines (and hacker-cred ;) ) are worth added confusion or risk of angry developer attacking me with a blunt instrument after they had to debug the code for previous fortnight. diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5582410..f985d16 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -200,28 +200,31 @@ extern int _cond_resched(void); #define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0) -/* - * abs() handles unsigned and signed longs, ints, shorts and chars. For all - * input types abs() returns a signed long. - * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64() - * for those. +/** + * abs - return absolute value of an argument + * @x: the value. If it is unsigned type, it is converted to signed type first + * (s64, long or int depending on its size). + * + * Return: an absolute value of x. If x is 64-bit, macro's return type is s64, + * otherwise it is signed long. */ -#define abs(x) ({ \ - long ret; \ - if (sizeof(x) == sizeof(long)) { \ - long __x = (x); \ - ret = (__x < 0) ? -__x : __x; \ - } else { \ - int __x = (x); \ - ret = (__x < 0) ? -__x : __x; \ - } \ - ret; \ - }) - -#define abs64(x) ({ \ - s64 __x = (x); \ - (__x < 0) ? -__x : __x; \ - }) +#define abs(x) __builtin_choose_expr(sizeof(x) == sizeof(s64), ({ \ + s64 __x = (x); \ + (__x < 0) ? -__x : __x; \ + }), ({ \ + long ret; \ + if (sizeof(x) == sizeof(long)) { \ + long __x = (x); \ + ret = (__x < 0) ? -__x : __x; \ + } else { \ + int __x = (x); \ + ret = (__x < 0) ? -__x : __x; \ + } \ + ret; \ + })) + +/* Deprecated, use abs instead. */ +#define abs64(x) abs((s64)(x)) /** * reciprocal_scale - "scale" a value into range [0, ep_ro) -- 2.6.0.rc0.131.gf624c3d