aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/vmlinux.lds.h14
-rw-r--r--include/linux/compiler.h61
2 files changed, 72 insertions, 3 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 80744606bad1..e10beb5335c9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -45,6 +45,17 @@
45#define MCOUNT_REC() 45#define MCOUNT_REC()
46#endif 46#endif
47 47
48#ifdef CONFIG_TRACE_UNLIKELY_PROFILE
49#define LIKELY_PROFILE() VMLINUX_SYMBOL(__start_likely_profile) = .; \
50 *(_ftrace_likely) \
51 VMLINUX_SYMBOL(__stop_likely_profile) = .; \
52 VMLINUX_SYMBOL(__start_unlikely_profile) = .; \
53 *(_ftrace_unlikely) \
54 VMLINUX_SYMBOL(__stop_unlikely_profile) = .;
55#else
56#define LIKELY_PROFILE()
57#endif
58
48/* .data section */ 59/* .data section */
49#define DATA_DATA \ 60#define DATA_DATA \
50 *(.data) \ 61 *(.data) \
@@ -62,7 +73,8 @@
62 VMLINUX_SYMBOL(__stop___markers) = .; \ 73 VMLINUX_SYMBOL(__stop___markers) = .; \
63 VMLINUX_SYMBOL(__start___tracepoints) = .; \ 74 VMLINUX_SYMBOL(__start___tracepoints) = .; \
64 *(__tracepoints) \ 75 *(__tracepoints) \
65 VMLINUX_SYMBOL(__stop___tracepoints) = .; 76 VMLINUX_SYMBOL(__stop___tracepoints) = .; \
77 LIKELY_PROFILE()
66 78
67#define RO_DATA(align) \ 79#define RO_DATA(align) \
68 . = ALIGN((align)); \ 80 . = ALIGN((align)); \
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 98115d9d04da..935e30cfaf3c 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -59,8 +59,65 @@ extern void __chk_io_ptr(const volatile void __iomem *);
59 * specific implementations come from the above header files 59 * specific implementations come from the above header files
60 */ 60 */
61 61
62#define likely(x) __builtin_expect(!!(x), 1) 62#ifdef CONFIG_TRACE_UNLIKELY_PROFILE
63#define unlikely(x) __builtin_expect(!!(x), 0) 63struct ftrace_likely_data {
64 const char *func;
65 const char *file;
66 unsigned line;
67 unsigned long correct;
68 unsigned long incorrect;
69};
70void ftrace_likely_update(struct ftrace_likely_data *f, int val, int expect);
71
72#define likely_notrace(x) __builtin_expect(!!(x), 1)
73#define unlikely_notrace(x) __builtin_expect(!!(x), 0)
74
75#define likely_check(x) ({ \
76 int ______r; \
77 static struct ftrace_likely_data \
78 __attribute__((__aligned__(4))) \
79 __attribute__((section("_ftrace_likely"))) \
80 ______f = { \
81 .func = __func__, \
82 .file = __FILE__, \
83 .line = __LINE__, \
84 }; \
85 ______f.line = __LINE__; \
86 ______r = likely_notrace(x); \
87 ftrace_likely_update(&______f, ______r, 1); \
88 ______r; \
89 })
90#define unlikely_check(x) ({ \
91 int ______r; \
92 static struct ftrace_likely_data \
93 __attribute__((__aligned__(4))) \
94 __attribute__((section("_ftrace_unlikely"))) \
95 ______f = { \
96 .func = __func__, \
97 .file = __FILE__, \
98 .line = __LINE__, \
99 }; \
100 ______f.line = __LINE__; \
101 ______r = unlikely_notrace(x); \
102 ftrace_likely_update(&______f, ______r, 0); \
103 ______r; \
104 })
105
106/*
107 * Using __builtin_constant_p(x) to ignore cases where the return
108 * value is always the same. This idea is taken from a similar patch
109 * written by Daniel Walker.
110 */
111# ifndef likely
112# define likely(x) (__builtin_constant_p(x) ? !!(x) : likely_check(x))
113# endif
114# ifndef unlikely
115# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : unlikely_check(x))
116# endif
117#else
118# define likely(x) __builtin_expect(!!(x), 1)
119# define unlikely(x) __builtin_expect(!!(x), 0)
120#endif
64 121
65/* Optimization barrier */ 122/* Optimization barrier */
66#ifndef barrier 123#ifndef barrier