summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/compiler-gcc4.h18
-rw-r--r--include/linux/compiler.h9
-rw-r--r--include/linux/init.h8
-rw-r--r--include/linux/kernel.h8
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,