From: Xi Wang <xi.wang@gmail.com> Date: 2012-11-11 21:20:19
(1<<optname) is undefined behavior in C with a negative optname or
optname larger than 31. In those cases the result of the shift is
not necessarily zero (e.g., on x86).
This patch simplifies the code with a switch statement on optname.
It also allows the compiler to generate better code (e.g., using a
64-bit mask).
Signed-off-by: Xi Wang <xi.wang@gmail.com>
---
net/ipv4/ip_sockglue.c | 35 ++++++++++++++++++++++-------------
1 file changed, 22 insertions(+), 13 deletions(-)
From: Xi Wang <xi.wang@gmail.com> Date: 2012-11-11 22:18:58
On 11/11/12 5:02 PM, David Miller wrote:
This code is a fast bit test on purpose. You're making the
code slower.
No, it's the opposite. All modern compilers optimize switch cases
into a fast bit test. The original "smarter" code, however, hinders
the compiler determining the mask for a fast bit test. With this
patch, GCC is able to compute a better mask. You can check the
assembly.
- xi
From: David Laight <hidden> Date: 2012-11-12 14:06:07
quoted
quoted
This code is a fast bit test on purpose. You're making the
code slower.
No, it's the opposite. All modern compilers optimize switch cases
into a fast bit test.
'All modern' is probably an overstatement, 'recent gcc' might be valid.
Indeed, I even checked sparc64 with gcc-4.6 and it looks good.
Thanks for the clarification, I'll apply this, thanks.
The 'switch' version will have an extra conditional to detect
'out of range' values - even though we know they can't happen.
I'm not sure you can avoid that - even for an enum.
David
From: Xi Wang <xi.wang@gmail.com> Date: 2012-11-12 17:01:03
On 11/12/12 8:54 AM, David Laight wrote:
'All modern' is probably an overstatement, 'recent gcc' might be valid.
I agree if you consider gcc 3.4 released 8 years ago as "recent gcc",
or if you use a compiler other than gcc/clang/icc to compile the kernel.
The 'switch' version will have an extra conditional to detect
'out of range' values - even though we know they can't happen.
I'm not sure you can avoid that - even for an enum.
This out-of-range check is exactly what this patch wanted to add:
optname is a syscall parameter, and we should reject invalid optname
values before doing (1<<optname).
- xi