Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1224567 > unrolled thread
| Started by | John Stultz <john.stultz@linaro.org> |
|---|---|
| First post | 2015-09-15 03:10 +0200 |
| Last post | 2015-09-18 05:20 +0200 |
| Articles | 5 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[RFC][PATCH 5/5] abs(): Provide build error on passing 64bit value to abs() John Stultz <john.stultz@linaro.org> - 2015-09-15 03:10 +0200
Re: [RFC][PATCH 5/5] abs(): Provide build error on passing 64bit value to abs() Ingo Molnar <mingo@kernel.org> - 2015-09-15 07:30 +0200
Re: [RFC][PATCH 5/5] abs(): Provide build error on passing 64bit value to abs() Linus Torvalds <torvalds@linux-foundation.org> - 2015-09-16 02:00 +0200
[PATCH] kernel.h: make abs() work with 64-bit types Michal Nazarewicz <mina86@mina86.com> - 2015-09-16 15:00 +0200
Re: [PATCH] kernel.h: make abs() work with 64-bit types John Stultz <john.stultz@linaro.org> - 2015-09-18 05:20 +0200
| From | John Stultz <john.stultz@linaro.org> |
|---|---|
| Date | 2015-09-15 03:10 +0200 |
| Subject | [RFC][PATCH 5/5] abs(): Provide build error on passing 64bit value to abs() |
| Message-ID | <q8MUW-6nq-13@gated-at.bofh.it> |
As noted in the comment above abs():
"abs() should not be used for 64-bit types (s64, u64, long long)
- use abs64() for those."
Unfortunately, its quite easy to pass 64-bit values to abs()
accidentally, and the compiler provides no warning when the
returned value is erroniously capped at 32-bits.
So this patch tries to make it easier to detect when 64-bit
values are passed to abs() by generating a build error.
Obviously, since this causes build errors, this patch is last
in the series, and I tried to fix up all of the issues I ran
into in my build testing. But there are likely still some out
there.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
include/linux/kernel.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5582410..6f01151 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -208,6 +208,9 @@ extern int _cond_resched(void);
*/
#define abs(x) ({ \
long ret; \
+ compiletime_assert( \
+ !(sizeof(typeof(x)) > sizeof(long)), \
+ "abs() should not be used for 64-bit types - use abs64()");\
if (sizeof(x) == sizeof(long)) { \
long __x = (x); \
ret = (__x < 0) ? -__x : __x; \
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2015-09-15 07:30 +0200 |
| Subject | Re: [RFC][PATCH 5/5] abs(): Provide build error on passing 64bit value to abs() |
| Message-ID | <q8QYy-3JQ-5@gated-at.bofh.it> |
| In reply to | #1224567 |
* John Stultz <john.stultz@linaro.org> wrote:
> As noted in the comment above abs():
> "abs() should not be used for 64-bit types (s64, u64, long long)
> - use abs64() for those."
>
> Unfortunately, its quite easy to pass 64-bit values to abs()
> accidentally, and the compiler provides no warning when the
> returned value is erroniously capped at 32-bits.
>
> So this patch tries to make it easier to detect when 64-bit
> values are passed to abs() by generating a build error.
>
> Obviously, since this causes build errors, this patch is last
> in the series, and I tried to fix up all of the issues I ran
> into in my build testing. But there are likely still some out
> there.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Michal Nazarewicz <mina86@mina86.com>
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
> include/linux/kernel.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 5582410..6f01151 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -208,6 +208,9 @@ extern int _cond_resched(void);
> */
> #define abs(x) ({ \
> long ret; \
> + compiletime_assert( \
> + !(sizeof(typeof(x)) > sizeof(long)), \
> + "abs() should not be used for 64-bit types - use abs64()");\
> if (sizeof(x) == sizeof(long)) { \
> long __x = (x); \
> ret = (__x < 0) ? -__x : __x; \
I think this should be a compiletime_warning() - that will be visible enough.
Thanks,
Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2015-09-16 02:00 +0200 |
| Subject | Re: [RFC][PATCH 5/5] abs(): Provide build error on passing 64bit value to abs() |
| Message-ID | <q98iL-4c5-27@gated-at.bofh.it> |
| In reply to | #1224646 |
On Mon, Sep 14, 2015 at 10:22 PM, Ingo Molnar <mingo@kernel.org> wrote:
>
> I think this should be a compiletime_warning() - that will be visible enough.
So the problem with this is that by now most kernel developers are on 64-bit.
And that "sizeof(typeof(x)) > sizeof(long))" would effectively never
trigger on 64-bit architectures, so almost no core developers would
see it. Yes, it would be caught by buildbots etc, but that's really
not very convenient. The new errors would be noticed too late, because
the actual *developers* wouldn't see them.
(Not to mention that the "typeof()" in that expression is redundant ;)
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.
Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Michal Nazarewicz <mina86@mina86.com> |
|---|---|
| Date | 2015-09-16 15:00 +0200 |
| Subject | [PATCH] kernel.h: make abs() work with 64-bit types |
| Message-ID | <q9ktA-4U2-15@gated-at.bofh.it> |
| In reply to | #1225601 |
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 <mina86@mina86.com>
---
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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | John Stultz <john.stultz@linaro.org> |
|---|---|
| Date | 2015-09-18 05:20 +0200 |
| Subject | Re: [PATCH] kernel.h: make abs() work with 64-bit types |
| Message-ID | <q9Unn-782-5@gated-at.bofh.it> |
| In reply to | #1226064 |
On Wed, Sep 16, 2015 at 5:57 AM, Michal Nazarewicz <mina86@mina86.com> wrote: > 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 <mina86@mina86.com> Sorry this is a little late, but I did run this patch through my tests on a 32bit system (against 4.2, since my localized fix has already landed in Linus' head) to make sure it resolved the bug I saw and it did. So, Tested-by: John Stultz <john.stultz@linaro.org> thanks! -john -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web