Skip to content

Commit

Permalink
[PATCH] Optimize PDA accesses slightly
Browse files Browse the repository at this point in the history
Based on a idea by Jeremy Fitzhardinge:

Replace the volatiles and memory clobbers in the PDA access with
telling gcc about access to a proxy PDA structure that doesn't
actually exist. But the dummy accesses give a defined ordering for
read/write accesses.

Also add some memory barriers to the early GS initialization to
make sure no PDA access is moved before it.

Advantage is some .text savings (probably most from better
code for accessing "current"):

   text    data     bss     dec     hex filename
4845647 1223688  615864 6685199  66020f vmlinux
4837780 1223688  615864 6677332  65e354 vmlinux-pda

1.2% smaller code

Cc:  Jeremy Fitzhardinge <jeremy@goop.org>
Signed-off-by: Andi Kleen <ak@suse.de>
  • Loading branch information
Andi Kleen authored and Andi Kleen committed Sep 26, 2006
1 parent 80d2679 commit 53ee11a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
3 changes: 3 additions & 0 deletions arch/x86_64/kernel/setup64.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ void pda_init(int cpu)

/* Setup up data that may be needed in __get_free_pages early */
asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
/* Memory clobbers used to order PDA accessed */
mb();
wrmsrl(MSR_GS_BASE, pda);
mb();

pda->cpunumber = cpu;
pda->irqcount = -1;
Expand Down
41 changes: 22 additions & 19 deletions include/asm-x86_64/pda.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,40 +36,43 @@ extern struct x8664_pda boot_cpu_pda[];
* There is no fast way to get the base address of the PDA, all the accesses
* have to mention %fs/%gs. So it needs to be done this Torvaldian way.
*/
#define sizeof_field(type,field) (sizeof(((type *)0)->field))
#define typeof_field(type,field) typeof(((type *)0)->field)

extern void __bad_pda_field(void);

/* proxy_pda doesn't actually exist, but tell gcc it is accessed
for all PDA accesses so it gets read/write dependencies right. */
extern struct x8664_pda _proxy_pda;

#define pda_offset(field) offsetof(struct x8664_pda, field)

#define pda_to_op(op,field,val) do { \
typedef typeof_field(struct x8664_pda, field) T__; \
switch (sizeof_field(struct x8664_pda, field)) { \
typedef typeof(_proxy_pda.field) T__; \
switch (sizeof(_proxy_pda.field)) { \
case 2: \
asm volatile(op "w %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
asm(op "w %1,%%gs:%P2" : "+m" (_proxy_pda.field) : \
"ri" ((T__)val),"i"(pda_offset(field))); break; \
case 4: \
asm volatile(op "l %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
asm(op "l %1,%%gs:%P2" : "+m" (_proxy_pda.field) : \
"ri" ((T__)val),"i"(pda_offset(field))); break; \
case 8: \
asm volatile(op "q %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
default: __bad_pda_field(); \
asm(op "q %1,%%gs:%P2": "+m" (_proxy_pda.field) : \
"ri" ((T__)val),"i"(pda_offset(field))); break; \
default: __bad_pda_field(); \
} \
} while (0)

/*
* AK: PDA read accesses should be neither volatile nor have an memory clobber.
* Unfortunately removing them causes all hell to break lose currently.
*/
#define pda_from_op(op,field) ({ \
typeof_field(struct x8664_pda, field) ret__; \
switch (sizeof_field(struct x8664_pda, field)) { \
typeof(_proxy_pda.field) ret__; \
switch (sizeof(_proxy_pda.field)) { \
case 2: \
asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
asm(op "w %%gs:%P1,%0":"=r" (ret__):\
"i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\
case 4: \
asm volatile(op "l %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
asm(op "l %%gs:%P1,%0":"=r" (ret__):\
"i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\
case 8: \
asm volatile(op "q %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
default: __bad_pda_field(); \
asm(op "q %%gs:%P1,%0":"=r" (ret__):\
"i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\
default: __bad_pda_field(); \
} \
ret__; })

Expand Down

0 comments on commit 53ee11a

Please sign in to comment.