diff options
-rw-r--r-- | include/linux/compiler-gcc4.h | 18 | ||||
-rw-r--r-- | include/linux/compiler.h | 9 | ||||
-rw-r--r-- | include/linux/init.h | 8 | ||||
-rw-r--r-- | include/linux/kernel.h | 8 |
4 files changed, 35 insertions, 8 deletions
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index a03e9398a6c..14f7494280f 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h @@ -23,3 +23,21 @@ * code */ #define uninitialized_var(x) x = x + +#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 3) +/* Mark functions as cold. gcc will assume any path leading to a call + to them will be unlikely. This means a lot of manual unlikely()s + are unnecessary now for any paths leading to the usual suspects + like BUG(), printk(), panic() etc. [but let's keep them for now for + older compilers] + + Early snapshots of gcc 4.3 don't support this and we can't detect this + in the preprocessor, but we can live with this because they're unreleased. + Maketime probing would be overkill here. + + gcc also has a __attribute__((__hot__)) to move hot functions into + a special section, but I don't see any sense in this right now in + the kernel context */ +#define __cold __attribute__((__cold__)) + +#endif diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 8287a72bb6a..12a1291855e 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -174,4 +174,13 @@ extern void __chk_io_ptr(const void __iomem *); # define __attribute_const__ /* unimplemented */ #endif +/* + * Tell gcc if a function is cold. The compiler will assume any path + * directly leading to the call is unlikely. + */ + +#ifndef __cold +#define __cold +#endif + #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/init.h b/include/linux/init.h index 5b528531633..f0d0e3295a9 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -40,10 +40,10 @@ /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __attribute__ ((__section__ (".init.text"))) +#define __init __attribute__ ((__section__ (".init.text"))) __cold #define __initdata __attribute__ ((__section__ (".init.data"))) #define __exitdata __attribute__ ((__section__(".exit.data"))) -#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) +#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) __cold /* modpost check for section mismatches during the kernel build. * A section mismatch happens when there are references from a @@ -59,9 +59,9 @@ #define __initdata_refok __attribute__ ((__section__ (".data.init.refok"))) #ifdef MODULE -#define __exit __attribute__ ((__section__(".exit.text"))) +#define __exit __attribute__ ((__section__(".exit.text"))) __cold #else -#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text"))) +#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text"))) __cold #endif /* For assembly routines */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 1eb9cde550c..4300bb462d2 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -106,7 +106,7 @@ extern int cond_resched(void); extern struct atomic_notifier_head panic_notifier_list; extern long (*panic_blink)(long time); NORET_TYPE void panic(const char * fmt, ...) - __attribute__ ((NORET_AND format (printf, 1, 2))); + __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; extern void oops_enter(void); extern void oops_exit(void); extern int oops_may_print(void); @@ -155,14 +155,14 @@ extern void dump_thread(struct pt_regs *regs, struct user *dump); asmlinkage int vprintk(const char *fmt, va_list args) __attribute__ ((format (printf, 1, 0))); asmlinkage int printk(const char * fmt, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute__ ((format (printf, 1, 2))) __cold; #else static inline int vprintk(const char *s, va_list args) __attribute__ ((format (printf, 1, 0))); static inline int vprintk(const char *s, va_list args) { return 0; } static inline int printk(const char *s, ...) __attribute__ ((format (printf, 1, 2))); -static inline int printk(const char *s, ...) { return 0; } +static inline int __cold printk(const char *s, ...) { return 0; } #endif unsigned long int_sqrt(unsigned long); @@ -212,7 +212,7 @@ extern enum system_states { #define TAINT_USER (1<<6) #define TAINT_DIE (1<<7) -extern void dump_stack(void); +extern void dump_stack(void) __cold; enum { DUMP_PREFIX_NONE, |