Introduce load_TLS to the "for" loop.
PATCH 1/1 Introduce load_TLS to the "for" loop.
GCC (4.1 at least) unrolls it anyway, but I can't believe this code was ever justifiable. (I've also submitted a patch which cleans up i386, which is even uglier).
include/asm-x86_64/desc.h +4 -7
@@ -135,16 +135,13 @@ static inline void set_ldt_desc(unsigned (info)->useable == 0 && \ (info)->lm == 0) -#if TLS_SIZE !=24 -# error update this code. -#endif -static inline void load_TLS (struct thread_struct *t,unsigned int cpu) { +unsigned int i;u64 *gdt = (u64 *)(cpu_gdt (cpu) +GDT_ENTRY_TLS_MIN ); - gdt[0 ] = t->tls_array[0 ]; - gdt[1 ] = t->tls_array[1 ]; - gdt[2 ] = t->tls_array[2 ]; + +for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) + gdt[i] = t->tls_array[i]; }/*
Quoted 1 line · Rusty Russell
GCC (4.1 at least) unrolls it anyway, but I can't believe this code
Are you sure? Normally it doesn't unroll without -funroll-loops which the kernel does normally not set. Especially not with -Os builds.
-Andi
Quoted 8 lines · Andi Kleen
Quoted 2 lines · Rusty Russell
GCC (4.1 at least) unrolls it anyway, but I can't believe this code
Are you sure? Normally it doesn't unroll without -funroll-loops which the kernel does normally not set. Especially not with -Os builds.
Does it matter either way in this case?
J
Quoted 11 lines · Jeremy Fitzhardinge
Quoted 8 lines · Andi Kleen
Quoted 2 lines · Rusty Russell
GCC (4.1 at least) unrolls it anyway, but I can't believe this code
Are you sure? Normally it doesn't unroll without -funroll-loops which the kernel does normally not set. Especially not with -Os builds.
Does it matter either way in this case?
It's in the middle of the context switch.
-Andi
Quoted 7 lines · Andi Kleen
Quoted 6 lines · Jeremy Fitzhardinge
Quoted 5 lines · Andi Kleen
Quoted 2 lines · Rusty Russell
GCC (4.1 at least) unrolls it anyway, but I can't believe this code
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Are you sure? Normally it doesn't unroll without -funroll-loops which the kernel does normally not set. Especially not with -Os builds.
Does it matter either way in this case?
It's in the middle of the context switch.
Well, the rest of __switch_to isn't "0PTIM1Z3D!!!" like this.
But even so, that's no excuse for crap code. If it had used memcpy, we wouldn't be wasting cycles on this discussion.
Rusty.
Quoted 5 lines · Andi Kleen
Quoted 1 line · Rusty Russell
GCC (4.1 at least) unrolls it anyway, but I can't believe this code
Are you sure? Normally it doesn't unroll without -funroll-loops which the kernel does normally not set. Especially not with -Os builds.
Yep, checked again:
$ gcc --version
gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)
...
...
gcc -Wp,-MD,arch/x86_64/kernel/.process.o.d -nostdinc
-isystem /usr/lib/gcc/i486-linux-gnu/4.1.2/include -D__KERNEL__
-Iinclude -include include/linux/autoconf.h -Wall -Wundef
-Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2
-mtune=generic -m64 -mno-red-zone -mcmodel=kernel -pipe
-fno-reorder-blocks -Wno-sign-compare -fno-asynchronous-unwind-tables
-funit-at-a-time -mno-sse -mno-mmx -mno-sse2 -mno-3dnow
-maccumulate-outgoing-args -fno-omit-frame-pointer
-fno-optimize-sibling-calls -g -fno-stack-protector
-Wdeclaration-after-statement -Wno-pointer-sign -D"KBUILD_STR(s)=#s"
-D"KBUILD_BASENAME=KBUILD_STR(process)"
-D"KBUILD_MODNAME=KBUILD_STR(process)" -c -o
arch/x86_64/kernel/process.o arch/x86_64/kernel/process.c
...
$ objdump -Dr arch/x86_64/kernel/process.o | less
...
6be: 48 8b 94 00 00 00 00 mov 0x0(%rax,%rax,1),%rdx
6c5: 00
6c2: R_X86_64_32S cpu_gdt_descr+0x2
6c6: 48 8b 83 98 02 00 00 mov 0x298(%rbx),%rax
6cd: 48 83 c2 60 add $0x60,%rdx
6d1: 48 89 02 mov %rax,(%rdx)
6d4: 48 8b 83 a0 02 00 00 mov 0x2a0(%rbx),%rax
6db: 48 89 42 08 mov %rax,0x8(%rdx)
6df: 48 8b 83 a8 02 00 00 mov 0x2a8(%rbx),%rax
6e6: 48 89 42 10 mov %rax,0x10(%rdx)If I turn on CONFIG_OPTIMIZE_FOR_SIZE, it's still unrolled, interestingly.
Cheers,
Rusty.