get_current() can be made __attribute__((const)) as it's not allowed to change under you, except in switch_to() (it's fine to violate the constness there since this switches stacks too, and will almost certainly do this in assembly code). This allows the compiler more choices about when it can cache this pointer. This doesn't break cached copies of current, whether they're cached by gcc in registers or on the stack. switch_to() will save all registers on the stack before actually switching, then when it switches current, it will also switch the stack and then pop back what was stored in the 'unclobbered' registers for the now active task and stack. Thus the copies of current that were cached just work. Note that does not affect all arches under all circumstances. Some arches, at least some of the time, keep current in a register, and some use thread_info as the source of current. This has been the norm on ARM and MN10300 arches (the latter only when not using E2 to hold current) for a while now. I've also tested this on x86_64. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> --- arch/powerpc/include/asm/current.h | 3 ++- arch/x86/include/asm/current.h | 3 ++- include/asm-generic/current.h | 9 ++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/current.h b/arch/powerpc/include/asm/current.h index 4ca5126..affcbbe 100644 --- a/arch/powerpc/include/asm/current.h +++ b/arch/powerpc/include/asm/current.h @@ -15,7 +15,8 @@ struct task_struct; #include <linux/stddef.h> #include <asm/paca.h> -static inline struct task_struct *get_current(void) +static inline __attribute_const__ +struct task_struct *get_current(void) { struct task_struct *task; diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h index 4d447b7..defb13c 100644 --- a/arch/x86/include/asm/current.h +++ b/arch/x86/include/asm/current.h @@ -9,7 +9,8 @@ struct task_struct; DECLARE_PER_CPU(struct task_struct *, current_task); -static __always_inline struct task_struct *get_current(void) +static __always_inline __attribute_const__ +struct task_struct *get_current(void) { return percpu_read_stable(current_task); } diff --git a/include/asm-generic/current.h b/include/asm-generic/current.h index 5e86f6a..8deb67e 100644 --- a/include/asm-generic/current.h +++ b/include/asm-generic/current.h @@ -3,7 +3,14 @@ #include <linux/thread_info.h> -#define get_current() (current_thread_info()->task) +struct task_struct; + +static inline __attribute_const__ +struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + #define current get_current() #endif /* __ASM_GENERIC_CURRENT_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html