diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/compiler.h | 2 | ||||
| -rw-r--r-- | include/linux/ftrace.h | 84 | ||||
| -rw-r--r-- | include/linux/init.h | 2 | ||||
| -rw-r--r-- | include/linux/kernel.h | 5 | ||||
| -rw-r--r-- | include/linux/kprobes.h | 5 | ||||
| -rw-r--r-- | include/linux/linkage.h | 2 | ||||
| -rw-r--r-- | include/linux/marker.h | 7 | ||||
| -rw-r--r-- | include/linux/mmiotrace.h | 20 | ||||
| -rw-r--r-- | include/linux/module.h | 17 | ||||
| -rw-r--r-- | include/linux/ring_buffer.h | 127 | ||||
| -rw-r--r-- | include/linux/tracepoint.h | 137 |
11 files changed, 393 insertions, 15 deletions
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 8322141ee480..98115d9d04da 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
| @@ -44,6 +44,8 @@ extern void __chk_io_ptr(const volatile void __iomem *); | |||
| 44 | # error Sorry, your compiler is too old/not recognized. | 44 | # error Sorry, your compiler is too old/not recognized. |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #define notrace __attribute__((no_instrument_function)) | ||
| 48 | |||
| 47 | /* Intel compiler defines __GNUC__. So we will overwrite implementations | 49 | /* Intel compiler defines __GNUC__. So we will overwrite implementations |
| 48 | * coming from above header files here | 50 | * coming from above header files here |
| 49 | */ | 51 | */ |
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index bb384068272e..a3d46151be19 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
| @@ -1,10 +1,14 @@ | |||
| 1 | #ifndef _LINUX_FTRACE_H | 1 | #ifndef _LINUX_FTRACE_H |
| 2 | #define _LINUX_FTRACE_H | 2 | #define _LINUX_FTRACE_H |
| 3 | 3 | ||
| 4 | #ifdef CONFIG_FTRACE | ||
| 5 | |||
| 6 | #include <linux/linkage.h> | 4 | #include <linux/linkage.h> |
| 7 | #include <linux/fs.h> | 5 | #include <linux/fs.h> |
| 6 | #include <linux/ktime.h> | ||
| 7 | #include <linux/init.h> | ||
| 8 | #include <linux/types.h> | ||
| 9 | #include <linux/kallsyms.h> | ||
| 10 | |||
| 11 | #ifdef CONFIG_FTRACE | ||
| 8 | 12 | ||
| 9 | extern int ftrace_enabled; | 13 | extern int ftrace_enabled; |
| 10 | extern int | 14 | extern int |
| @@ -36,6 +40,7 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1); | |||
| 36 | # define register_ftrace_function(ops) do { } while (0) | 40 | # define register_ftrace_function(ops) do { } while (0) |
| 37 | # define unregister_ftrace_function(ops) do { } while (0) | 41 | # define unregister_ftrace_function(ops) do { } while (0) |
| 38 | # define clear_ftrace_function(ops) do { } while (0) | 42 | # define clear_ftrace_function(ops) do { } while (0) |
| 43 | static inline void ftrace_kill_atomic(void) { } | ||
| 39 | #endif /* CONFIG_FTRACE */ | 44 | #endif /* CONFIG_FTRACE */ |
| 40 | 45 | ||
| 41 | #ifdef CONFIG_DYNAMIC_FTRACE | 46 | #ifdef CONFIG_DYNAMIC_FTRACE |
| @@ -76,8 +81,10 @@ extern void mcount_call(void); | |||
| 76 | 81 | ||
| 77 | extern int skip_trace(unsigned long ip); | 82 | extern int skip_trace(unsigned long ip); |
| 78 | 83 | ||
| 79 | void ftrace_disable_daemon(void); | 84 | extern void ftrace_release(void *start, unsigned long size); |
| 80 | void ftrace_enable_daemon(void); | 85 | |
| 86 | extern void ftrace_disable_daemon(void); | ||
| 87 | extern void ftrace_enable_daemon(void); | ||
| 81 | 88 | ||
| 82 | #else | 89 | #else |
| 83 | # define skip_trace(ip) ({ 0; }) | 90 | # define skip_trace(ip) ({ 0; }) |
| @@ -85,6 +92,7 @@ void ftrace_enable_daemon(void); | |||
| 85 | # define ftrace_set_filter(buf, len, reset) do { } while (0) | 92 | # define ftrace_set_filter(buf, len, reset) do { } while (0) |
| 86 | # define ftrace_disable_daemon() do { } while (0) | 93 | # define ftrace_disable_daemon() do { } while (0) |
| 87 | # define ftrace_enable_daemon() do { } while (0) | 94 | # define ftrace_enable_daemon() do { } while (0) |
| 95 | static inline void ftrace_release(void *start, unsigned long size) { } | ||
| 88 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 96 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
| 89 | 97 | ||
| 90 | /* totally disable ftrace - can not re-enable after this */ | 98 | /* totally disable ftrace - can not re-enable after this */ |
| @@ -98,9 +106,11 @@ static inline void tracer_disable(void) | |||
| 98 | #endif | 106 | #endif |
| 99 | } | 107 | } |
| 100 | 108 | ||
| 101 | /* Ftrace disable/restore without lock. Some synchronization mechanism | 109 | /* |
| 110 | * Ftrace disable/restore without lock. Some synchronization mechanism | ||
| 102 | * must be used to prevent ftrace_enabled to be changed between | 111 | * must be used to prevent ftrace_enabled to be changed between |
| 103 | * disable/restore. */ | 112 | * disable/restore. |
| 113 | */ | ||
| 104 | static inline int __ftrace_enabled_save(void) | 114 | static inline int __ftrace_enabled_save(void) |
| 105 | { | 115 | { |
| 106 | #ifdef CONFIG_FTRACE | 116 | #ifdef CONFIG_FTRACE |
| @@ -157,9 +167,71 @@ static inline void __ftrace_enabled_restore(int enabled) | |||
| 157 | #ifdef CONFIG_TRACING | 167 | #ifdef CONFIG_TRACING |
| 158 | extern void | 168 | extern void |
| 159 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); | 169 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); |
| 170 | |||
| 171 | /** | ||
| 172 | * ftrace_printk - printf formatting in the ftrace buffer | ||
| 173 | * @fmt: the printf format for printing | ||
| 174 | * | ||
| 175 | * Note: __ftrace_printk is an internal function for ftrace_printk and | ||
| 176 | * the @ip is passed in via the ftrace_printk macro. | ||
| 177 | * | ||
| 178 | * This function allows a kernel developer to debug fast path sections | ||
| 179 | * that printk is not appropriate for. By scattering in various | ||
| 180 | * printk like tracing in the code, a developer can quickly see | ||
| 181 | * where problems are occurring. | ||
| 182 | * | ||
| 183 | * This is intended as a debugging tool for the developer only. | ||
| 184 | * Please refrain from leaving ftrace_printks scattered around in | ||
| 185 | * your code. | ||
| 186 | */ | ||
| 187 | # define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt) | ||
| 188 | extern int | ||
| 189 | __ftrace_printk(unsigned long ip, const char *fmt, ...) | ||
| 190 | __attribute__ ((format (printf, 2, 3))); | ||
| 191 | extern void ftrace_dump(void); | ||
| 160 | #else | 192 | #else |
| 161 | static inline void | 193 | static inline void |
| 162 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } | 194 | ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } |
| 195 | static inline int | ||
| 196 | ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))); | ||
| 197 | |||
| 198 | static inline int | ||
| 199 | ftrace_printk(const char *fmt, ...) | ||
| 200 | { | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | static inline void ftrace_dump(void) { } | ||
| 163 | #endif | 204 | #endif |
| 164 | 205 | ||
| 206 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||
| 207 | extern void ftrace_init(void); | ||
| 208 | extern void ftrace_init_module(unsigned long *start, unsigned long *end); | ||
| 209 | #else | ||
| 210 | static inline void ftrace_init(void) { } | ||
| 211 | static inline void | ||
| 212 | ftrace_init_module(unsigned long *start, unsigned long *end) { } | ||
| 213 | #endif | ||
| 214 | |||
| 215 | |||
| 216 | struct boot_trace { | ||
| 217 | pid_t caller; | ||
| 218 | char func[KSYM_NAME_LEN]; | ||
| 219 | int result; | ||
| 220 | unsigned long long duration; /* usecs */ | ||
| 221 | ktime_t calltime; | ||
| 222 | ktime_t rettime; | ||
| 223 | }; | ||
| 224 | |||
| 225 | #ifdef CONFIG_BOOT_TRACER | ||
| 226 | extern void trace_boot(struct boot_trace *it, initcall_t fn); | ||
| 227 | extern void start_boot_trace(void); | ||
| 228 | extern void stop_boot_trace(void); | ||
| 229 | #else | ||
| 230 | static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } | ||
| 231 | static inline void start_boot_trace(void) { } | ||
| 232 | static inline void stop_boot_trace(void) { } | ||
| 233 | #endif | ||
| 234 | |||
| 235 | |||
| 236 | |||
| 165 | #endif /* _LINUX_FTRACE_H */ | 237 | #endif /* _LINUX_FTRACE_H */ |
diff --git a/include/linux/init.h b/include/linux/init.h index ad63824460e3..0c1264668be0 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | /* These are for everybody (although not all archs will actually | 41 | /* These are for everybody (although not all archs will actually |
| 42 | discard it in modules) */ | 42 | discard it in modules) */ |
| 43 | #define __init __section(.init.text) __cold | 43 | #define __init __section(.init.text) __cold notrace |
| 44 | #define __initdata __section(.init.data) | 44 | #define __initdata __section(.init.data) |
| 45 | #define __initconst __section(.init.rodata) | 45 | #define __initconst __section(.init.rodata) |
| 46 | #define __exitdata __section(.exit.data) | 46 | #define __exitdata __section(.exit.data) |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5a566b705ca9..94d17ff64c5a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -496,4 +496,9 @@ struct sysinfo { | |||
| 496 | #define NUMA_BUILD 0 | 496 | #define NUMA_BUILD 0 |
| 497 | #endif | 497 | #endif |
| 498 | 498 | ||
| 499 | /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ | ||
| 500 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||
| 501 | # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD | ||
| 502 | #endif | ||
| 503 | |||
| 499 | #endif | 504 | #endif |
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 0be7795655fa..497b1d1f7a05 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi | 29 | * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi |
| 30 | * <prasanna@in.ibm.com> added function-return probes. | 30 | * <prasanna@in.ibm.com> added function-return probes. |
| 31 | */ | 31 | */ |
| 32 | #include <linux/linkage.h> | ||
| 32 | #include <linux/list.h> | 33 | #include <linux/list.h> |
| 33 | #include <linux/notifier.h> | 34 | #include <linux/notifier.h> |
| 34 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
| @@ -47,7 +48,7 @@ | |||
| 47 | #define KPROBE_HIT_SSDONE 0x00000008 | 48 | #define KPROBE_HIT_SSDONE 0x00000008 |
| 48 | 49 | ||
| 49 | /* Attach to insert probes on any functions which should be ignored*/ | 50 | /* Attach to insert probes on any functions which should be ignored*/ |
| 50 | #define __kprobes __attribute__((__section__(".kprobes.text"))) | 51 | #define __kprobes __attribute__((__section__(".kprobes.text"))) notrace |
| 51 | 52 | ||
| 52 | struct kprobe; | 53 | struct kprobe; |
| 53 | struct pt_regs; | 54 | struct pt_regs; |
| @@ -256,7 +257,7 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head); | |||
| 256 | 257 | ||
| 257 | #else /* CONFIG_KPROBES */ | 258 | #else /* CONFIG_KPROBES */ |
| 258 | 259 | ||
| 259 | #define __kprobes /**/ | 260 | #define __kprobes notrace |
| 260 | struct jprobe; | 261 | struct jprobe; |
| 261 | struct kretprobe; | 262 | struct kretprobe; |
| 262 | 263 | ||
diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 56ba37394656..9fd1f859021b 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
| 5 | #include <asm/linkage.h> | 5 | #include <asm/linkage.h> |
| 6 | 6 | ||
| 7 | #define notrace __attribute__((no_instrument_function)) | ||
| 8 | |||
| 9 | #ifdef __cplusplus | 7 | #ifdef __cplusplus |
| 10 | #define CPP_ASMLINKAGE extern "C" | 8 | #define CPP_ASMLINKAGE extern "C" |
| 11 | #else | 9 | #else |
diff --git a/include/linux/marker.h b/include/linux/marker.h index 1290653f9241..889196c7fbb1 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
| @@ -160,4 +160,11 @@ extern int marker_probe_unregister_private_data(marker_probe_func *probe, | |||
| 160 | extern void *marker_get_private_data(const char *name, marker_probe_func *probe, | 160 | extern void *marker_get_private_data(const char *name, marker_probe_func *probe, |
| 161 | int num); | 161 | int num); |
| 162 | 162 | ||
| 163 | /* | ||
| 164 | * marker_synchronize_unregister must be called between the last marker probe | ||
| 165 | * unregistration and the end of module exit to make sure there is no caller | ||
| 166 | * executing a probe when it is freed. | ||
| 167 | */ | ||
| 168 | #define marker_synchronize_unregister() synchronize_sched() | ||
| 169 | |||
| 163 | #endif | 170 | #endif |
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 61d19e1b7a0b..139d7c88d9c9 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h | |||
| @@ -34,11 +34,15 @@ extern void unregister_kmmio_probe(struct kmmio_probe *p); | |||
| 34 | /* Called from page fault handler. */ | 34 | /* Called from page fault handler. */ |
| 35 | extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); | 35 | extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); |
| 36 | 36 | ||
| 37 | /* Called from ioremap.c */ | ||
| 38 | #ifdef CONFIG_MMIOTRACE | 37 | #ifdef CONFIG_MMIOTRACE |
| 38 | /* Called from ioremap.c */ | ||
| 39 | extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, | 39 | extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, |
| 40 | void __iomem *addr); | 40 | void __iomem *addr); |
| 41 | extern void mmiotrace_iounmap(volatile void __iomem *addr); | 41 | extern void mmiotrace_iounmap(volatile void __iomem *addr); |
| 42 | |||
| 43 | /* For anyone to insert markers. Remember trailing newline. */ | ||
| 44 | extern int mmiotrace_printk(const char *fmt, ...) | ||
| 45 | __attribute__ ((format (printf, 1, 2))); | ||
| 42 | #else | 46 | #else |
| 43 | static inline void mmiotrace_ioremap(resource_size_t offset, | 47 | static inline void mmiotrace_ioremap(resource_size_t offset, |
| 44 | unsigned long size, void __iomem *addr) | 48 | unsigned long size, void __iomem *addr) |
| @@ -48,15 +52,22 @@ static inline void mmiotrace_ioremap(resource_size_t offset, | |||
| 48 | static inline void mmiotrace_iounmap(volatile void __iomem *addr) | 52 | static inline void mmiotrace_iounmap(volatile void __iomem *addr) |
| 49 | { | 53 | { |
| 50 | } | 54 | } |
| 51 | #endif /* CONFIG_MMIOTRACE_HOOKS */ | 55 | |
| 56 | static inline int mmiotrace_printk(const char *fmt, ...) | ||
| 57 | __attribute__ ((format (printf, 1, 0))); | ||
| 58 | |||
| 59 | static inline int mmiotrace_printk(const char *fmt, ...) | ||
| 60 | { | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | #endif /* CONFIG_MMIOTRACE */ | ||
| 52 | 64 | ||
| 53 | enum mm_io_opcode { | 65 | enum mm_io_opcode { |
| 54 | MMIO_READ = 0x1, /* struct mmiotrace_rw */ | 66 | MMIO_READ = 0x1, /* struct mmiotrace_rw */ |
| 55 | MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ | 67 | MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ |
| 56 | MMIO_PROBE = 0x3, /* struct mmiotrace_map */ | 68 | MMIO_PROBE = 0x3, /* struct mmiotrace_map */ |
| 57 | MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ | 69 | MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ |
| 58 | MMIO_MARKER = 0x5, /* raw char data */ | 70 | MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */ |
| 59 | MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */ | ||
| 60 | }; | 71 | }; |
| 61 | 72 | ||
| 62 | struct mmiotrace_rw { | 73 | struct mmiotrace_rw { |
| @@ -81,5 +92,6 @@ extern void enable_mmiotrace(void); | |||
| 81 | extern void disable_mmiotrace(void); | 92 | extern void disable_mmiotrace(void); |
| 82 | extern void mmio_trace_rw(struct mmiotrace_rw *rw); | 93 | extern void mmio_trace_rw(struct mmiotrace_rw *rw); |
| 83 | extern void mmio_trace_mapping(struct mmiotrace_map *map); | 94 | extern void mmio_trace_mapping(struct mmiotrace_map *map); |
| 95 | extern int mmio_trace_printk(const char *fmt, va_list args); | ||
| 84 | 96 | ||
| 85 | #endif /* MMIOTRACE_H */ | 97 | #endif /* MMIOTRACE_H */ |
diff --git a/include/linux/module.h b/include/linux/module.h index a41555cbe00a..5d2970cdce93 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/kobject.h> | 16 | #include <linux/kobject.h> |
| 17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
| 18 | #include <linux/marker.h> | 18 | #include <linux/marker.h> |
| 19 | #include <linux/tracepoint.h> | ||
| 19 | #include <asm/local.h> | 20 | #include <asm/local.h> |
| 20 | 21 | ||
| 21 | #include <asm/module.h> | 22 | #include <asm/module.h> |
| @@ -331,6 +332,10 @@ struct module | |||
| 331 | struct marker *markers; | 332 | struct marker *markers; |
| 332 | unsigned int num_markers; | 333 | unsigned int num_markers; |
| 333 | #endif | 334 | #endif |
| 335 | #ifdef CONFIG_TRACEPOINTS | ||
| 336 | struct tracepoint *tracepoints; | ||
| 337 | unsigned int num_tracepoints; | ||
| 338 | #endif | ||
| 334 | 339 | ||
| 335 | #ifdef CONFIG_MODULE_UNLOAD | 340 | #ifdef CONFIG_MODULE_UNLOAD |
| 336 | /* What modules depend on me? */ | 341 | /* What modules depend on me? */ |
| @@ -453,6 +458,9 @@ extern void print_modules(void); | |||
| 453 | 458 | ||
| 454 | extern void module_update_markers(void); | 459 | extern void module_update_markers(void); |
| 455 | 460 | ||
| 461 | extern void module_update_tracepoints(void); | ||
| 462 | extern int module_get_iter_tracepoints(struct tracepoint_iter *iter); | ||
| 463 | |||
| 456 | #else /* !CONFIG_MODULES... */ | 464 | #else /* !CONFIG_MODULES... */ |
| 457 | #define EXPORT_SYMBOL(sym) | 465 | #define EXPORT_SYMBOL(sym) |
| 458 | #define EXPORT_SYMBOL_GPL(sym) | 466 | #define EXPORT_SYMBOL_GPL(sym) |
| @@ -557,6 +565,15 @@ static inline void module_update_markers(void) | |||
| 557 | { | 565 | { |
| 558 | } | 566 | } |
| 559 | 567 | ||
| 568 | static inline void module_update_tracepoints(void) | ||
| 569 | { | ||
| 570 | } | ||
| 571 | |||
| 572 | static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter) | ||
| 573 | { | ||
| 574 | return 0; | ||
| 575 | } | ||
| 576 | |||
| 560 | #endif /* CONFIG_MODULES */ | 577 | #endif /* CONFIG_MODULES */ |
| 561 | 578 | ||
| 562 | struct device_driver; | 579 | struct device_driver; |
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h new file mode 100644 index 000000000000..536b0ca46a03 --- /dev/null +++ b/include/linux/ring_buffer.h | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | #ifndef _LINUX_RING_BUFFER_H | ||
| 2 | #define _LINUX_RING_BUFFER_H | ||
| 3 | |||
| 4 | #include <linux/mm.h> | ||
| 5 | #include <linux/seq_file.h> | ||
| 6 | |||
| 7 | struct ring_buffer; | ||
| 8 | struct ring_buffer_iter; | ||
| 9 | |||
| 10 | /* | ||
| 11 | * Don't reference this struct directly, use functions below. | ||
| 12 | */ | ||
| 13 | struct ring_buffer_event { | ||
| 14 | u32 type:2, len:3, time_delta:27; | ||
| 15 | u32 array[]; | ||
| 16 | }; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * enum ring_buffer_type - internal ring buffer types | ||
| 20 | * | ||
| 21 | * @RINGBUF_TYPE_PADDING: Left over page padding | ||
| 22 | * array is ignored | ||
| 23 | * size is variable depending on how much | ||
| 24 | * padding is needed | ||
| 25 | * | ||
| 26 | * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta | ||
| 27 | * array[0] = time delta (28 .. 59) | ||
| 28 | * size = 8 bytes | ||
| 29 | * | ||
| 30 | * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock | ||
| 31 | * array[0] = tv_nsec | ||
| 32 | * array[1] = tv_sec | ||
| 33 | * size = 16 bytes | ||
| 34 | * | ||
| 35 | * @RINGBUF_TYPE_DATA: Data record | ||
| 36 | * If len is zero: | ||
| 37 | * array[0] holds the actual length | ||
| 38 | * array[1..(length+3)/4-1] holds data | ||
| 39 | * else | ||
| 40 | * length = len << 2 | ||
| 41 | * array[0..(length+3)/4] holds data | ||
| 42 | */ | ||
| 43 | enum ring_buffer_type { | ||
| 44 | RINGBUF_TYPE_PADDING, | ||
| 45 | RINGBUF_TYPE_TIME_EXTEND, | ||
| 46 | /* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */ | ||
| 47 | RINGBUF_TYPE_TIME_STAMP, | ||
| 48 | RINGBUF_TYPE_DATA, | ||
| 49 | }; | ||
| 50 | |||
| 51 | unsigned ring_buffer_event_length(struct ring_buffer_event *event); | ||
| 52 | void *ring_buffer_event_data(struct ring_buffer_event *event); | ||
| 53 | |||
| 54 | /** | ||
| 55 | * ring_buffer_event_time_delta - return the delta timestamp of the event | ||
| 56 | * @event: the event to get the delta timestamp of | ||
| 57 | * | ||
| 58 | * The delta timestamp is the 27 bit timestamp since the last event. | ||
| 59 | */ | ||
| 60 | static inline unsigned | ||
| 61 | ring_buffer_event_time_delta(struct ring_buffer_event *event) | ||
| 62 | { | ||
| 63 | return event->time_delta; | ||
| 64 | } | ||
| 65 | |||
| 66 | /* | ||
| 67 | * size is in bytes for each per CPU buffer. | ||
| 68 | */ | ||
| 69 | struct ring_buffer * | ||
| 70 | ring_buffer_alloc(unsigned long size, unsigned flags); | ||
| 71 | void ring_buffer_free(struct ring_buffer *buffer); | ||
| 72 | |||
| 73 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size); | ||
| 74 | |||
| 75 | struct ring_buffer_event * | ||
| 76 | ring_buffer_lock_reserve(struct ring_buffer *buffer, | ||
| 77 | unsigned long length, | ||
| 78 | unsigned long *flags); | ||
| 79 | int ring_buffer_unlock_commit(struct ring_buffer *buffer, | ||
| 80 | struct ring_buffer_event *event, | ||
| 81 | unsigned long flags); | ||
| 82 | int ring_buffer_write(struct ring_buffer *buffer, | ||
| 83 | unsigned long length, void *data); | ||
| 84 | |||
| 85 | struct ring_buffer_event * | ||
| 86 | ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts); | ||
| 87 | struct ring_buffer_event * | ||
| 88 | ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts); | ||
| 89 | |||
| 90 | struct ring_buffer_iter * | ||
| 91 | ring_buffer_read_start(struct ring_buffer *buffer, int cpu); | ||
| 92 | void ring_buffer_read_finish(struct ring_buffer_iter *iter); | ||
| 93 | |||
| 94 | struct ring_buffer_event * | ||
| 95 | ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts); | ||
| 96 | struct ring_buffer_event * | ||
| 97 | ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts); | ||
| 98 | void ring_buffer_iter_reset(struct ring_buffer_iter *iter); | ||
| 99 | int ring_buffer_iter_empty(struct ring_buffer_iter *iter); | ||
| 100 | |||
| 101 | unsigned long ring_buffer_size(struct ring_buffer *buffer); | ||
| 102 | |||
| 103 | void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu); | ||
| 104 | void ring_buffer_reset(struct ring_buffer *buffer); | ||
| 105 | |||
| 106 | int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, | ||
| 107 | struct ring_buffer *buffer_b, int cpu); | ||
| 108 | |||
| 109 | int ring_buffer_empty(struct ring_buffer *buffer); | ||
| 110 | int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); | ||
| 111 | |||
| 112 | void ring_buffer_record_disable(struct ring_buffer *buffer); | ||
| 113 | void ring_buffer_record_enable(struct ring_buffer *buffer); | ||
| 114 | void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); | ||
| 115 | void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); | ||
| 116 | |||
| 117 | unsigned long ring_buffer_entries(struct ring_buffer *buffer); | ||
| 118 | unsigned long ring_buffer_overruns(struct ring_buffer *buffer); | ||
| 119 | |||
| 120 | u64 ring_buffer_time_stamp(int cpu); | ||
| 121 | void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); | ||
| 122 | |||
| 123 | enum ring_buffer_flags { | ||
| 124 | RB_FL_OVERWRITE = 1 << 0, | ||
| 125 | }; | ||
| 126 | |||
| 127 | #endif /* _LINUX_RING_BUFFER_H */ | ||
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h new file mode 100644 index 000000000000..c5bb39c7a770 --- /dev/null +++ b/include/linux/tracepoint.h | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | #ifndef _LINUX_TRACEPOINT_H | ||
| 2 | #define _LINUX_TRACEPOINT_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Kernel Tracepoint API. | ||
| 6 | * | ||
| 7 | * See Documentation/tracepoint.txt. | ||
| 8 | * | ||
| 9 | * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | ||
| 10 | * | ||
| 11 | * Heavily inspired from the Linux Kernel Markers. | ||
| 12 | * | ||
| 13 | * This file is released under the GPLv2. | ||
| 14 | * See the file COPYING for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/rcupdate.h> | ||
| 19 | |||
| 20 | struct module; | ||
| 21 | struct tracepoint; | ||
| 22 | |||
| 23 | struct tracepoint { | ||
| 24 | const char *name; /* Tracepoint name */ | ||
| 25 | int state; /* State. */ | ||
| 26 | void **funcs; | ||
| 27 | } __attribute__((aligned(8))); | ||
| 28 | |||
| 29 | |||
| 30 | #define TPPROTO(args...) args | ||
| 31 | #define TPARGS(args...) args | ||
| 32 | |||
| 33 | #ifdef CONFIG_TRACEPOINTS | ||
| 34 | |||
| 35 | /* | ||
| 36 | * it_func[0] is never NULL because there is at least one element in the array | ||
| 37 | * when the array itself is non NULL. | ||
| 38 | */ | ||
| 39 | #define __DO_TRACE(tp, proto, args) \ | ||
| 40 | do { \ | ||
| 41 | void **it_func; \ | ||
| 42 | \ | ||
| 43 | rcu_read_lock_sched(); \ | ||
| 44 | it_func = rcu_dereference((tp)->funcs); \ | ||
| 45 | if (it_func) { \ | ||
| 46 | do { \ | ||
| 47 | ((void(*)(proto))(*it_func))(args); \ | ||
| 48 | } while (*(++it_func)); \ | ||
| 49 | } \ | ||
| 50 | rcu_read_unlock_sched(); \ | ||
| 51 | } while (0) | ||
| 52 | |||
| 53 | /* | ||
| 54 | * Make sure the alignment of the structure in the __tracepoints section will | ||
| 55 | * not add unwanted padding between the beginning of the section and the | ||
| 56 | * structure. Force alignment to the same alignment as the section start. | ||
| 57 | */ | ||
| 58 | #define DEFINE_TRACE(name, proto, args) \ | ||
| 59 | static inline void trace_##name(proto) \ | ||
| 60 | { \ | ||
| 61 | static const char __tpstrtab_##name[] \ | ||
| 62 | __attribute__((section("__tracepoints_strings"))) \ | ||
| 63 | = #name ":" #proto; \ | ||
| 64 | static struct tracepoint __tracepoint_##name \ | ||
| 65 | __attribute__((section("__tracepoints"), aligned(8))) = \ | ||
| 66 | { __tpstrtab_##name, 0, NULL }; \ | ||
| 67 | if (unlikely(__tracepoint_##name.state)) \ | ||
| 68 | __DO_TRACE(&__tracepoint_##name, \ | ||
| 69 | TPPROTO(proto), TPARGS(args)); \ | ||
| 70 | } \ | ||
| 71 | static inline int register_trace_##name(void (*probe)(proto)) \ | ||
| 72 | { \ | ||
| 73 | return tracepoint_probe_register(#name ":" #proto, \ | ||
| 74 | (void *)probe); \ | ||
| 75 | } \ | ||
| 76 | static inline void unregister_trace_##name(void (*probe)(proto))\ | ||
| 77 | { \ | ||
| 78 | tracepoint_probe_unregister(#name ":" #proto, \ | ||
| 79 | (void *)probe); \ | ||
| 80 | } | ||
| 81 | |||
| 82 | extern void tracepoint_update_probe_range(struct tracepoint *begin, | ||
| 83 | struct tracepoint *end); | ||
| 84 | |||
| 85 | #else /* !CONFIG_TRACEPOINTS */ | ||
| 86 | #define DEFINE_TRACE(name, proto, args) \ | ||
| 87 | static inline void _do_trace_##name(struct tracepoint *tp, proto) \ | ||
| 88 | { } \ | ||
| 89 | static inline void trace_##name(proto) \ | ||
| 90 | { } \ | ||
| 91 | static inline int register_trace_##name(void (*probe)(proto)) \ | ||
| 92 | { \ | ||
| 93 | return -ENOSYS; \ | ||
| 94 | } \ | ||
| 95 | static inline void unregister_trace_##name(void (*probe)(proto))\ | ||
| 96 | { } | ||
| 97 | |||
| 98 | static inline void tracepoint_update_probe_range(struct tracepoint *begin, | ||
| 99 | struct tracepoint *end) | ||
| 100 | { } | ||
| 101 | #endif /* CONFIG_TRACEPOINTS */ | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Connect a probe to a tracepoint. | ||
| 105 | * Internal API, should not be used directly. | ||
| 106 | */ | ||
| 107 | extern int tracepoint_probe_register(const char *name, void *probe); | ||
| 108 | |||
| 109 | /* | ||
| 110 | * Disconnect a probe from a tracepoint. | ||
| 111 | * Internal API, should not be used directly. | ||
| 112 | */ | ||
| 113 | extern int tracepoint_probe_unregister(const char *name, void *probe); | ||
| 114 | |||
| 115 | struct tracepoint_iter { | ||
| 116 | struct module *module; | ||
| 117 | struct tracepoint *tracepoint; | ||
| 118 | }; | ||
| 119 | |||
| 120 | extern void tracepoint_iter_start(struct tracepoint_iter *iter); | ||
| 121 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); | ||
| 122 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); | ||
| 123 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); | ||
| 124 | extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, | ||
| 125 | struct tracepoint *begin, struct tracepoint *end); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * tracepoint_synchronize_unregister must be called between the last tracepoint | ||
| 129 | * probe unregistration and the end of module exit to make sure there is no | ||
| 130 | * caller executing a probe when it is freed. | ||
| 131 | */ | ||
| 132 | static inline void tracepoint_synchronize_unregister(void) | ||
| 133 | { | ||
| 134 | synchronize_sched(); | ||
| 135 | } | ||
| 136 | |||
| 137 | #endif | ||
