It is ok to call prefetch() function with NULL argument, as specifically
commented in include/linux/prefetch.h. But in standard C, it is invalid to
dereference NULL pointer (see C99 standard 6.5.3.2 paragraph 4 and note #84).
Newer gcc versions (4.3 and above) will use that to conclude that "x"
argument is non-null and thus wreaking havok everywhere prefetch() was inlined.
Fixed by removing cast and changing asm constraint.
This can be fixed better by using gcc's __builtin_prefetch().
Signed-off-by: Serge Belyshev <[email protected]>
---
include/asm-x86_64/processor.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux/include/asm-x86_64/processor.h
===================================================================
--- linux.orig/include/asm-x86_64/processor.h
+++ linux/include/asm-x86_64/processor.h
@@ -373,7 +373,7 @@ static inline void sync_core(void)
#define ARCH_HAS_PREFETCH
static inline void prefetch(void *x)
{
- asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
+ asm volatile("prefetcht0 (%0)" :: "r" (x));
}
#define ARCH_HAS_PREFETCHW 1
On Thursday 06 September 2007 22:27, Serge Belyshev wrote:
> It is ok to call prefetch() function with NULL argument, as specifically
> commented in include/linux/prefetch.h. But in standard C, it is invalid to
> dereference NULL pointer (see C99 standard 6.5.3.2 paragraph 4 and note
> #84). Newer gcc versions (4.3 and above) will use that to conclude that "x"
> argument is non-null and thus wreaking havok everywhere prefetch() was
> inlined. Fixed by removing cast and changing asm constraint.
>
> This can be fixed better by using gcc's __builtin_prefetch().
I changed it to just use that. Thanks.
It seems like gcc 3.1/3.2 already supported it and that's the earliest gcc
still supported so it can be used unconditionally.
-Andi
Andi Kleen <[email protected]> writes:
>> This can be fixed better by using gcc's __builtin_prefetch().
>
> I changed it to just use that. Thanks.
>
> It seems like gcc 3.1/3.2 already supported it and that's the earliest gcc
> still supported so it can be used unconditionally.
>
Hi!
Will you submit this patch for inclusion into 2.6.23? It is important
to make kernel work with GCC 4.3 and above. (Also note that gcc 4.2 already
smart enough to break that code, but kernel is just lucky currently).
On Sat, Sep 15, 2007 at 10:40:26AM +0400, Serge Belyshev wrote:
> Andi Kleen <[email protected]> writes:
>
> >> This can be fixed better by using gcc's __builtin_prefetch().
> >
> > I changed it to just use that. Thanks.
> >
> > It seems like gcc 3.1/3.2 already supported it and that's the earliest gcc
> > still supported so it can be used unconditionally.
> >
>
> Hi!
>
> Will you submit this patch for inclusion into 2.6.23? It is important
Didn't plan it currently.
> to make kernel work with GCC 4.3 and above. (Also note that gcc 4.2 already
> smart enough to break that code, but kernel is just lucky currently).
How would it break the code exactly? It more sounded like an optimization
to me. Would it generate incorrect code without it?
-Andi
Andi Kleen <[email protected]> writes:
...
>> to make kernel work with GCC 4.3 and above. (Also note that gcc 4.2 already
>> smart enough to break that code, but kernel is just lucky currently).
>
> How would it break the code exactly? It more sounded like an optimization
> to me. Would it generate incorrect code without it?
See http://gcc.gnu.org/PR33294 for testcase which fails if compiled with gcc 4.2
and above. Yes, incorrect code can be generated without the patch as demonstrated by
testcase, but i didn't analyze why kernel appears to work with 4.2 currently.