diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-05 18:30:21 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-05 18:30:21 -0500 |
| commit | c3fa27d1367fac63ac8533d6f20ea851d0d70a10 (patch) | |
| tree | e7731554085e22b6b63411b1ebb401079f3e0bbb /include/linux | |
| parent | 96fa2b508d2d3fe040cf4ef2fffb955f0a537ea1 (diff) | |
| parent | d103d01e4b19f185d3c85f77402b605534c32e89 (diff) | |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (470 commits)
x86: Fix comments of register/stack access functions
perf tools: Replace %m with %a in sscanf
hw-breakpoints: Keep track of user disabled breakpoints
tracing/syscalls: Make syscall events print callbacks static
tracing: Add DEFINE_EVENT(), DEFINE_SINGLE_EVENT() support to docbook
perf: Don't free perf_mmap_data until work has been done
perf_event: Fix compile error
perf tools: Fix _GNU_SOURCE macro related strndup() build error
trace_syscalls: Remove unused syscall_name_to_nr()
trace_syscalls: Simplify syscall profile
trace_syscalls: Remove duplicate init_enter_##sname()
trace_syscalls: Add syscall_nr field to struct syscall_metadata
trace_syscalls: Remove enter_id exit_id
trace_syscalls: Set event_enter_##sname->data to its metadata
trace_syscalls: Remove unused event_syscall_enter and event_syscall_exit
perf_event: Initialize data.period in perf_swevent_hrtimer()
perf probe: Simplify event naming
perf probe: Add --list option for listing current probe events
perf probe: Add argv_split() from lib/argv_split.c
perf probe: Move probe event utility functions to probe-event.c
...
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/ftrace_event.h | 38 | ||||
| -rw-r--r-- | include/linux/hw_breakpoint.h | 131 | ||||
| -rw-r--r-- | include/linux/kprobes.h | 2 | ||||
| -rw-r--r-- | include/linux/perf_counter.h | 3 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 59 | ||||
| -rw-r--r-- | include/linux/syscalls.h | 77 | ||||
| -rw-r--r-- | include/linux/tracepoint.h | 6 |
7 files changed, 236 insertions, 80 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 4ec5e67e18cf..47bbdf9c38d0 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
| @@ -117,12 +117,12 @@ struct ftrace_event_call { | |||
| 117 | struct dentry *dir; | 117 | struct dentry *dir; |
| 118 | struct trace_event *event; | 118 | struct trace_event *event; |
| 119 | int enabled; | 119 | int enabled; |
| 120 | int (*regfunc)(void *); | 120 | int (*regfunc)(struct ftrace_event_call *); |
| 121 | void (*unregfunc)(void *); | 121 | void (*unregfunc)(struct ftrace_event_call *); |
| 122 | int id; | 122 | int id; |
| 123 | int (*raw_init)(void); | 123 | int (*raw_init)(struct ftrace_event_call *); |
| 124 | int (*show_format)(struct ftrace_event_call *call, | 124 | int (*show_format)(struct ftrace_event_call *, |
| 125 | struct trace_seq *s); | 125 | struct trace_seq *); |
| 126 | int (*define_fields)(struct ftrace_event_call *); | 126 | int (*define_fields)(struct ftrace_event_call *); |
| 127 | struct list_head fields; | 127 | struct list_head fields; |
| 128 | int filter_active; | 128 | int filter_active; |
| @@ -131,20 +131,20 @@ struct ftrace_event_call { | |||
| 131 | void *data; | 131 | void *data; |
| 132 | 132 | ||
| 133 | atomic_t profile_count; | 133 | atomic_t profile_count; |
| 134 | int (*profile_enable)(void); | 134 | int (*profile_enable)(struct ftrace_event_call *); |
| 135 | void (*profile_disable)(void); | 135 | void (*profile_disable)(struct ftrace_event_call *); |
| 136 | }; | 136 | }; |
| 137 | 137 | ||
| 138 | #define FTRACE_MAX_PROFILE_SIZE 2048 | 138 | #define FTRACE_MAX_PROFILE_SIZE 2048 |
| 139 | 139 | ||
| 140 | extern char *trace_profile_buf; | 140 | extern char *perf_trace_buf; |
| 141 | extern char *trace_profile_buf_nmi; | 141 | extern char *perf_trace_buf_nmi; |
| 142 | 142 | ||
| 143 | #define MAX_FILTER_PRED 32 | 143 | #define MAX_FILTER_PRED 32 |
| 144 | #define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ | 144 | #define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ |
| 145 | 145 | ||
| 146 | extern void destroy_preds(struct ftrace_event_call *call); | 146 | extern void destroy_preds(struct ftrace_event_call *call); |
| 147 | extern int filter_match_preds(struct ftrace_event_call *call, void *rec); | 147 | extern int filter_match_preds(struct event_filter *filter, void *rec); |
| 148 | extern int filter_current_check_discard(struct ring_buffer *buffer, | 148 | extern int filter_current_check_discard(struct ring_buffer *buffer, |
| 149 | struct ftrace_event_call *call, | 149 | struct ftrace_event_call *call, |
| 150 | void *rec, | 150 | void *rec, |
| @@ -157,11 +157,12 @@ enum { | |||
| 157 | FILTER_PTR_STRING, | 157 | FILTER_PTR_STRING, |
| 158 | }; | 158 | }; |
| 159 | 159 | ||
| 160 | extern int trace_define_field(struct ftrace_event_call *call, | ||
| 161 | const char *type, const char *name, | ||
| 162 | int offset, int size, int is_signed, | ||
| 163 | int filter_type); | ||
| 164 | extern int trace_define_common_fields(struct ftrace_event_call *call); | 160 | extern int trace_define_common_fields(struct ftrace_event_call *call); |
| 161 | extern int trace_define_field(struct ftrace_event_call *call, const char *type, | ||
| 162 | const char *name, int offset, int size, | ||
| 163 | int is_signed, int filter_type); | ||
| 164 | extern int trace_add_event_call(struct ftrace_event_call *call); | ||
| 165 | extern void trace_remove_event_call(struct ftrace_event_call *call); | ||
| 165 | 166 | ||
| 166 | #define is_signed_type(type) (((type)(-1)) < 0) | 167 | #define is_signed_type(type) (((type)(-1)) < 0) |
| 167 | 168 | ||
| @@ -186,4 +187,13 @@ do { \ | |||
| 186 | __trace_printk(ip, fmt, ##args); \ | 187 | __trace_printk(ip, fmt, ##args); \ |
| 187 | } while (0) | 188 | } while (0) |
| 188 | 189 | ||
| 190 | #ifdef CONFIG_EVENT_PROFILE | ||
| 191 | struct perf_event; | ||
| 192 | extern int ftrace_profile_enable(int event_id); | ||
| 193 | extern void ftrace_profile_disable(int event_id); | ||
| 194 | extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, | ||
| 195 | char *filter_str); | ||
| 196 | extern void ftrace_profile_free_filter(struct perf_event *event); | ||
| 197 | #endif | ||
| 198 | |||
| 189 | #endif /* _LINUX_FTRACE_EVENT_H */ | 199 | #endif /* _LINUX_FTRACE_EVENT_H */ |
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h new file mode 100644 index 000000000000..a03daed08c59 --- /dev/null +++ b/include/linux/hw_breakpoint.h | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | #ifndef _LINUX_HW_BREAKPOINT_H | ||
| 2 | #define _LINUX_HW_BREAKPOINT_H | ||
| 3 | |||
| 4 | enum { | ||
| 5 | HW_BREAKPOINT_LEN_1 = 1, | ||
| 6 | HW_BREAKPOINT_LEN_2 = 2, | ||
| 7 | HW_BREAKPOINT_LEN_4 = 4, | ||
| 8 | HW_BREAKPOINT_LEN_8 = 8, | ||
| 9 | }; | ||
| 10 | |||
| 11 | enum { | ||
| 12 | HW_BREAKPOINT_R = 1, | ||
| 13 | HW_BREAKPOINT_W = 2, | ||
| 14 | HW_BREAKPOINT_X = 4, | ||
| 15 | }; | ||
| 16 | |||
| 17 | #ifdef __KERNEL__ | ||
| 18 | |||
| 19 | #include <linux/perf_event.h> | ||
| 20 | |||
| 21 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 22 | |||
| 23 | /* As it's for in-kernel or ptrace use, we want it to be pinned */ | ||
| 24 | #define DEFINE_BREAKPOINT_ATTR(name) \ | ||
| 25 | struct perf_event_attr name = { \ | ||
| 26 | .type = PERF_TYPE_BREAKPOINT, \ | ||
| 27 | .size = sizeof(name), \ | ||
| 28 | .pinned = 1, \ | ||
| 29 | }; | ||
| 30 | |||
| 31 | static inline void hw_breakpoint_init(struct perf_event_attr *attr) | ||
| 32 | { | ||
| 33 | attr->type = PERF_TYPE_BREAKPOINT; | ||
| 34 | attr->size = sizeof(*attr); | ||
| 35 | attr->pinned = 1; | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) | ||
| 39 | { | ||
| 40 | return bp->attr.bp_addr; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline int hw_breakpoint_type(struct perf_event *bp) | ||
| 44 | { | ||
| 45 | return bp->attr.bp_type; | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline int hw_breakpoint_len(struct perf_event *bp) | ||
| 49 | { | ||
| 50 | return bp->attr.bp_len; | ||
| 51 | } | ||
| 52 | |||
| 53 | extern struct perf_event * | ||
| 54 | register_user_hw_breakpoint(struct perf_event_attr *attr, | ||
| 55 | perf_callback_t triggered, | ||
| 56 | struct task_struct *tsk); | ||
| 57 | |||
| 58 | /* FIXME: only change from the attr, and don't unregister */ | ||
| 59 | extern struct perf_event * | ||
| 60 | modify_user_hw_breakpoint(struct perf_event *bp, | ||
| 61 | struct perf_event_attr *attr, | ||
| 62 | perf_callback_t triggered, | ||
| 63 | struct task_struct *tsk); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Kernel breakpoints are not associated with any particular thread. | ||
| 67 | */ | ||
| 68 | extern struct perf_event * | ||
| 69 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | ||
| 70 | perf_callback_t triggered, | ||
| 71 | int cpu); | ||
| 72 | |||
| 73 | extern struct perf_event ** | ||
| 74 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | ||
| 75 | perf_callback_t triggered); | ||
| 76 | |||
| 77 | extern int register_perf_hw_breakpoint(struct perf_event *bp); | ||
| 78 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); | ||
| 79 | extern void unregister_hw_breakpoint(struct perf_event *bp); | ||
| 80 | extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events); | ||
| 81 | |||
| 82 | extern int reserve_bp_slot(struct perf_event *bp); | ||
| 83 | extern void release_bp_slot(struct perf_event *bp); | ||
| 84 | |||
| 85 | extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk); | ||
| 86 | |||
| 87 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | ||
| 88 | { | ||
| 89 | return &bp->hw.info; | ||
| 90 | } | ||
| 91 | |||
| 92 | #else /* !CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 93 | |||
| 94 | static inline struct perf_event * | ||
| 95 | register_user_hw_breakpoint(struct perf_event_attr *attr, | ||
| 96 | perf_callback_t triggered, | ||
| 97 | struct task_struct *tsk) { return NULL; } | ||
| 98 | static inline struct perf_event * | ||
| 99 | modify_user_hw_breakpoint(struct perf_event *bp, | ||
| 100 | struct perf_event_attr *attr, | ||
| 101 | perf_callback_t triggered, | ||
| 102 | struct task_struct *tsk) { return NULL; } | ||
| 103 | static inline struct perf_event * | ||
| 104 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | ||
| 105 | perf_callback_t triggered, | ||
| 106 | int cpu) { return NULL; } | ||
| 107 | static inline struct perf_event ** | ||
| 108 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | ||
| 109 | perf_callback_t triggered) { return NULL; } | ||
| 110 | static inline int | ||
| 111 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | ||
| 112 | static inline int | ||
| 113 | __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | ||
| 114 | static inline void unregister_hw_breakpoint(struct perf_event *bp) { } | ||
| 115 | static inline void | ||
| 116 | unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { } | ||
| 117 | static inline int | ||
| 118 | reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } | ||
| 119 | static inline void release_bp_slot(struct perf_event *bp) { } | ||
| 120 | |||
| 121 | static inline void flush_ptrace_hw_breakpoint(struct task_struct *tsk) { } | ||
| 122 | |||
| 123 | static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | ||
| 124 | { | ||
| 125 | return NULL; | ||
| 126 | } | ||
| 127 | |||
| 128 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
| 129 | #endif /* __KERNEL__ */ | ||
| 130 | |||
| 131 | #endif /* _LINUX_HW_BREAKPOINT_H */ | ||
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 3a46b7b7abb2..1b672f74a32f 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
| @@ -296,6 +296,8 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head); | |||
| 296 | int disable_kprobe(struct kprobe *kp); | 296 | int disable_kprobe(struct kprobe *kp); |
| 297 | int enable_kprobe(struct kprobe *kp); | 297 | int enable_kprobe(struct kprobe *kp); |
| 298 | 298 | ||
| 299 | void dump_kprobe(struct kprobe *kp); | ||
| 300 | |||
| 299 | #else /* !CONFIG_KPROBES: */ | 301 | #else /* !CONFIG_KPROBES: */ |
| 300 | 302 | ||
| 301 | static inline int kprobes_built_in(void) | 303 | static inline int kprobes_built_in(void) |
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 7b7fbf433cff..e3fb25606706 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h | |||
| @@ -106,6 +106,8 @@ enum perf_sw_ids { | |||
| 106 | PERF_COUNT_SW_CPU_MIGRATIONS = 4, | 106 | PERF_COUNT_SW_CPU_MIGRATIONS = 4, |
| 107 | PERF_COUNT_SW_PAGE_FAULTS_MIN = 5, | 107 | PERF_COUNT_SW_PAGE_FAULTS_MIN = 5, |
| 108 | PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6, | 108 | PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6, |
| 109 | PERF_COUNT_SW_ALIGNMENT_FAULTS = 7, | ||
| 110 | PERF_COUNT_SW_EMULATION_FAULTS = 8, | ||
| 109 | 111 | ||
| 110 | PERF_COUNT_SW_MAX, /* non-ABI */ | 112 | PERF_COUNT_SW_MAX, /* non-ABI */ |
| 111 | }; | 113 | }; |
| @@ -225,6 +227,7 @@ struct perf_counter_attr { | |||
| 225 | #define PERF_COUNTER_IOC_RESET _IO ('$', 3) | 227 | #define PERF_COUNTER_IOC_RESET _IO ('$', 3) |
| 226 | #define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64) | 228 | #define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64) |
| 227 | #define PERF_COUNTER_IOC_SET_OUTPUT _IO ('$', 5) | 229 | #define PERF_COUNTER_IOC_SET_OUTPUT _IO ('$', 5) |
| 230 | #define PERF_COUNTER_IOC_SET_FILTER _IOW('$', 6, char *) | ||
| 228 | 231 | ||
| 229 | enum perf_counter_ioc_flags { | 232 | enum perf_counter_ioc_flags { |
| 230 | PERF_IOC_FLAG_GROUP = 1U << 0, | 233 | PERF_IOC_FLAG_GROUP = 1U << 0, |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 9e7012689a84..43adbd7f0010 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -18,6 +18,10 @@ | |||
| 18 | #include <linux/ioctl.h> | 18 | #include <linux/ioctl.h> |
| 19 | #include <asm/byteorder.h> | 19 | #include <asm/byteorder.h> |
| 20 | 20 | ||
| 21 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 22 | #include <asm/hw_breakpoint.h> | ||
| 23 | #endif | ||
| 24 | |||
| 21 | /* | 25 | /* |
| 22 | * User-space ABI bits: | 26 | * User-space ABI bits: |
| 23 | */ | 27 | */ |
| @@ -31,6 +35,7 @@ enum perf_type_id { | |||
| 31 | PERF_TYPE_TRACEPOINT = 2, | 35 | PERF_TYPE_TRACEPOINT = 2, |
| 32 | PERF_TYPE_HW_CACHE = 3, | 36 | PERF_TYPE_HW_CACHE = 3, |
| 33 | PERF_TYPE_RAW = 4, | 37 | PERF_TYPE_RAW = 4, |
| 38 | PERF_TYPE_BREAKPOINT = 5, | ||
| 34 | 39 | ||
| 35 | PERF_TYPE_MAX, /* non-ABI */ | 40 | PERF_TYPE_MAX, /* non-ABI */ |
| 36 | }; | 41 | }; |
| @@ -102,6 +107,8 @@ enum perf_sw_ids { | |||
| 102 | PERF_COUNT_SW_CPU_MIGRATIONS = 4, | 107 | PERF_COUNT_SW_CPU_MIGRATIONS = 4, |
| 103 | PERF_COUNT_SW_PAGE_FAULTS_MIN = 5, | 108 | PERF_COUNT_SW_PAGE_FAULTS_MIN = 5, |
| 104 | PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6, | 109 | PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6, |
| 110 | PERF_COUNT_SW_ALIGNMENT_FAULTS = 7, | ||
| 111 | PERF_COUNT_SW_EMULATION_FAULTS = 8, | ||
| 105 | 112 | ||
| 106 | PERF_COUNT_SW_MAX, /* non-ABI */ | 113 | PERF_COUNT_SW_MAX, /* non-ABI */ |
| 107 | }; | 114 | }; |
| @@ -207,6 +214,15 @@ struct perf_event_attr { | |||
| 207 | __u32 wakeup_events; /* wakeup every n events */ | 214 | __u32 wakeup_events; /* wakeup every n events */ |
| 208 | __u32 wakeup_watermark; /* bytes before wakeup */ | 215 | __u32 wakeup_watermark; /* bytes before wakeup */ |
| 209 | }; | 216 | }; |
| 217 | |||
| 218 | union { | ||
| 219 | struct { /* Hardware breakpoint info */ | ||
| 220 | __u64 bp_addr; | ||
| 221 | __u32 bp_type; | ||
| 222 | __u32 bp_len; | ||
| 223 | }; | ||
| 224 | }; | ||
| 225 | |||
| 210 | __u32 __reserved_2; | 226 | __u32 __reserved_2; |
| 211 | 227 | ||
| 212 | __u64 __reserved_3; | 228 | __u64 __reserved_3; |
| @@ -219,8 +235,9 @@ struct perf_event_attr { | |||
| 219 | #define PERF_EVENT_IOC_DISABLE _IO ('$', 1) | 235 | #define PERF_EVENT_IOC_DISABLE _IO ('$', 1) |
| 220 | #define PERF_EVENT_IOC_REFRESH _IO ('$', 2) | 236 | #define PERF_EVENT_IOC_REFRESH _IO ('$', 2) |
| 221 | #define PERF_EVENT_IOC_RESET _IO ('$', 3) | 237 | #define PERF_EVENT_IOC_RESET _IO ('$', 3) |
| 222 | #define PERF_EVENT_IOC_PERIOD _IOW('$', 4, u64) | 238 | #define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64) |
| 223 | #define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5) | 239 | #define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5) |
| 240 | #define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *) | ||
| 224 | 241 | ||
| 225 | enum perf_event_ioc_flags { | 242 | enum perf_event_ioc_flags { |
| 226 | PERF_IOC_FLAG_GROUP = 1U << 0, | 243 | PERF_IOC_FLAG_GROUP = 1U << 0, |
| @@ -475,6 +492,11 @@ struct hw_perf_event { | |||
| 475 | s64 remaining; | 492 | s64 remaining; |
| 476 | struct hrtimer hrtimer; | 493 | struct hrtimer hrtimer; |
| 477 | }; | 494 | }; |
| 495 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
| 496 | union { /* breakpoint */ | ||
| 497 | struct arch_hw_breakpoint info; | ||
| 498 | }; | ||
| 499 | #endif | ||
| 478 | }; | 500 | }; |
| 479 | atomic64_t prev_count; | 501 | atomic64_t prev_count; |
| 480 | u64 sample_period; | 502 | u64 sample_period; |
| @@ -543,6 +565,10 @@ struct perf_pending_entry { | |||
| 543 | void (*func)(struct perf_pending_entry *); | 565 | void (*func)(struct perf_pending_entry *); |
| 544 | }; | 566 | }; |
| 545 | 567 | ||
| 568 | typedef void (*perf_callback_t)(struct perf_event *, void *); | ||
| 569 | |||
| 570 | struct perf_sample_data; | ||
| 571 | |||
| 546 | /** | 572 | /** |
| 547 | * struct perf_event - performance event kernel representation: | 573 | * struct perf_event - performance event kernel representation: |
| 548 | */ | 574 | */ |
| @@ -585,7 +611,7 @@ struct perf_event { | |||
| 585 | u64 tstamp_running; | 611 | u64 tstamp_running; |
| 586 | u64 tstamp_stopped; | 612 | u64 tstamp_stopped; |
| 587 | 613 | ||
| 588 | struct perf_event_attr attr; | 614 | struct perf_event_attr attr; |
| 589 | struct hw_perf_event hw; | 615 | struct hw_perf_event hw; |
| 590 | 616 | ||
| 591 | struct perf_event_context *ctx; | 617 | struct perf_event_context *ctx; |
| @@ -633,7 +659,20 @@ struct perf_event { | |||
| 633 | 659 | ||
| 634 | struct pid_namespace *ns; | 660 | struct pid_namespace *ns; |
| 635 | u64 id; | 661 | u64 id; |
| 662 | |||
| 663 | void (*overflow_handler)(struct perf_event *event, | ||
| 664 | int nmi, struct perf_sample_data *data, | ||
| 665 | struct pt_regs *regs); | ||
| 666 | |||
| 667 | #ifdef CONFIG_EVENT_PROFILE | ||
| 668 | struct event_filter *filter; | ||
| 636 | #endif | 669 | #endif |
| 670 | |||
| 671 | perf_callback_t callback; | ||
| 672 | |||
| 673 | perf_callback_t event_callback; | ||
| 674 | |||
| 675 | #endif /* CONFIG_PERF_EVENTS */ | ||
| 637 | }; | 676 | }; |
| 638 | 677 | ||
| 639 | /** | 678 | /** |
| @@ -706,7 +745,6 @@ struct perf_output_handle { | |||
| 706 | int nmi; | 745 | int nmi; |
| 707 | int sample; | 746 | int sample; |
| 708 | int locked; | 747 | int locked; |
| 709 | unsigned long flags; | ||
| 710 | }; | 748 | }; |
| 711 | 749 | ||
| 712 | #ifdef CONFIG_PERF_EVENTS | 750 | #ifdef CONFIG_PERF_EVENTS |
| @@ -738,6 +776,14 @@ extern int hw_perf_group_sched_in(struct perf_event *group_leader, | |||
| 738 | struct perf_cpu_context *cpuctx, | 776 | struct perf_cpu_context *cpuctx, |
| 739 | struct perf_event_context *ctx, int cpu); | 777 | struct perf_event_context *ctx, int cpu); |
| 740 | extern void perf_event_update_userpage(struct perf_event *event); | 778 | extern void perf_event_update_userpage(struct perf_event *event); |
| 779 | extern int perf_event_release_kernel(struct perf_event *event); | ||
| 780 | extern struct perf_event * | ||
| 781 | perf_event_create_kernel_counter(struct perf_event_attr *attr, | ||
| 782 | int cpu, | ||
| 783 | pid_t pid, | ||
| 784 | perf_callback_t callback); | ||
| 785 | extern u64 perf_event_read_value(struct perf_event *event, | ||
| 786 | u64 *enabled, u64 *running); | ||
| 741 | 787 | ||
| 742 | struct perf_sample_data { | 788 | struct perf_sample_data { |
| 743 | u64 type; | 789 | u64 type; |
| @@ -814,6 +860,7 @@ extern int sysctl_perf_event_sample_rate; | |||
| 814 | extern void perf_event_init(void); | 860 | extern void perf_event_init(void); |
| 815 | extern void perf_tp_event(int event_id, u64 addr, u64 count, | 861 | extern void perf_tp_event(int event_id, u64 addr, u64 count, |
| 816 | void *record, int entry_size); | 862 | void *record, int entry_size); |
| 863 | extern void perf_bp_event(struct perf_event *event, void *data); | ||
| 817 | 864 | ||
| 818 | #ifndef perf_misc_flags | 865 | #ifndef perf_misc_flags |
| 819 | #define perf_misc_flags(regs) (user_mode(regs) ? PERF_RECORD_MISC_USER : \ | 866 | #define perf_misc_flags(regs) (user_mode(regs) ? PERF_RECORD_MISC_USER : \ |
| @@ -827,6 +874,8 @@ extern int perf_output_begin(struct perf_output_handle *handle, | |||
| 827 | extern void perf_output_end(struct perf_output_handle *handle); | 874 | extern void perf_output_end(struct perf_output_handle *handle); |
| 828 | extern void perf_output_copy(struct perf_output_handle *handle, | 875 | extern void perf_output_copy(struct perf_output_handle *handle, |
| 829 | const void *buf, unsigned int len); | 876 | const void *buf, unsigned int len); |
| 877 | extern int perf_swevent_get_recursion_context(void); | ||
| 878 | extern void perf_swevent_put_recursion_context(int rctx); | ||
| 830 | #else | 879 | #else |
| 831 | static inline void | 880 | static inline void |
| 832 | perf_event_task_sched_in(struct task_struct *task, int cpu) { } | 881 | perf_event_task_sched_in(struct task_struct *task, int cpu) { } |
| @@ -848,11 +897,15 @@ static inline int perf_event_task_enable(void) { return -EINVAL; } | |||
| 848 | static inline void | 897 | static inline void |
| 849 | perf_sw_event(u32 event_id, u64 nr, int nmi, | 898 | perf_sw_event(u32 event_id, u64 nr, int nmi, |
| 850 | struct pt_regs *regs, u64 addr) { } | 899 | struct pt_regs *regs, u64 addr) { } |
| 900 | static inline void | ||
| 901 | perf_bp_event(struct perf_event *event, void *data) { } | ||
| 851 | 902 | ||
| 852 | static inline void perf_event_mmap(struct vm_area_struct *vma) { } | 903 | static inline void perf_event_mmap(struct vm_area_struct *vma) { } |
| 853 | static inline void perf_event_comm(struct task_struct *tsk) { } | 904 | static inline void perf_event_comm(struct task_struct *tsk) { } |
| 854 | static inline void perf_event_fork(struct task_struct *tsk) { } | 905 | static inline void perf_event_fork(struct task_struct *tsk) { } |
| 855 | static inline void perf_event_init(void) { } | 906 | static inline void perf_event_init(void) { } |
| 907 | static inline int perf_swevent_get_recursion_context(void) { return -1; } | ||
| 908 | static inline void perf_swevent_put_recursion_context(int rctx) { } | ||
| 856 | 909 | ||
| 857 | #endif | 910 | #endif |
| 858 | 911 | ||
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a990ace1a838..e79e2f3ccc51 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -99,37 +99,16 @@ struct perf_event_attr; | |||
| 99 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) | 99 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) |
| 100 | 100 | ||
| 101 | #ifdef CONFIG_EVENT_PROFILE | 101 | #ifdef CONFIG_EVENT_PROFILE |
| 102 | #define TRACE_SYS_ENTER_PROFILE(sname) \ | ||
| 103 | static int prof_sysenter_enable_##sname(void) \ | ||
| 104 | { \ | ||
| 105 | return reg_prof_syscall_enter("sys"#sname); \ | ||
| 106 | } \ | ||
| 107 | \ | ||
| 108 | static void prof_sysenter_disable_##sname(void) \ | ||
| 109 | { \ | ||
| 110 | unreg_prof_syscall_enter("sys"#sname); \ | ||
| 111 | } | ||
| 112 | |||
| 113 | #define TRACE_SYS_EXIT_PROFILE(sname) \ | ||
| 114 | static int prof_sysexit_enable_##sname(void) \ | ||
| 115 | { \ | ||
| 116 | return reg_prof_syscall_exit("sys"#sname); \ | ||
| 117 | } \ | ||
| 118 | \ | ||
| 119 | static void prof_sysexit_disable_##sname(void) \ | ||
| 120 | { \ | ||
| 121 | unreg_prof_syscall_exit("sys"#sname); \ | ||
| 122 | } | ||
| 123 | 102 | ||
| 124 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | 103 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ |
| 125 | .profile_count = ATOMIC_INIT(-1), \ | 104 | .profile_count = ATOMIC_INIT(-1), \ |
| 126 | .profile_enable = prof_sysenter_enable_##sname, \ | 105 | .profile_enable = prof_sysenter_enable, \ |
| 127 | .profile_disable = prof_sysenter_disable_##sname, | 106 | .profile_disable = prof_sysenter_disable, |
| 128 | 107 | ||
| 129 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | 108 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ |
| 130 | .profile_count = ATOMIC_INIT(-1), \ | 109 | .profile_count = ATOMIC_INIT(-1), \ |
| 131 | .profile_enable = prof_sysexit_enable_##sname, \ | 110 | .profile_enable = prof_sysexit_enable, \ |
| 132 | .profile_disable = prof_sysexit_disable_##sname, | 111 | .profile_disable = prof_sysexit_disable, |
| 133 | #else | 112 | #else |
| 134 | #define TRACE_SYS_ENTER_PROFILE(sname) | 113 | #define TRACE_SYS_ENTER_PROFILE(sname) |
| 135 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) | 114 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) |
| @@ -153,74 +132,46 @@ static void prof_sysexit_disable_##sname(void) \ | |||
| 153 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | 132 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) |
| 154 | 133 | ||
| 155 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 134 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
| 135 | static const struct syscall_metadata __syscall_meta_##sname; \ | ||
| 156 | static struct ftrace_event_call event_enter_##sname; \ | 136 | static struct ftrace_event_call event_enter_##sname; \ |
| 157 | struct trace_event enter_syscall_print_##sname = { \ | 137 | static struct trace_event enter_syscall_print_##sname = { \ |
| 158 | .trace = print_syscall_enter, \ | 138 | .trace = print_syscall_enter, \ |
| 159 | }; \ | 139 | }; \ |
| 160 | static int init_enter_##sname(void) \ | ||
| 161 | { \ | ||
| 162 | int num, id; \ | ||
| 163 | num = syscall_name_to_nr("sys"#sname); \ | ||
| 164 | if (num < 0) \ | ||
| 165 | return -ENOSYS; \ | ||
| 166 | id = register_ftrace_event(&enter_syscall_print_##sname);\ | ||
| 167 | if (!id) \ | ||
| 168 | return -ENODEV; \ | ||
| 169 | event_enter_##sname.id = id; \ | ||
| 170 | set_syscall_enter_id(num, id); \ | ||
| 171 | INIT_LIST_HEAD(&event_enter_##sname.fields); \ | ||
| 172 | return 0; \ | ||
| 173 | } \ | ||
| 174 | TRACE_SYS_ENTER_PROFILE(sname); \ | ||
| 175 | static struct ftrace_event_call __used \ | 140 | static struct ftrace_event_call __used \ |
| 176 | __attribute__((__aligned__(4))) \ | 141 | __attribute__((__aligned__(4))) \ |
| 177 | __attribute__((section("_ftrace_events"))) \ | 142 | __attribute__((section("_ftrace_events"))) \ |
| 178 | event_enter_##sname = { \ | 143 | event_enter_##sname = { \ |
| 179 | .name = "sys_enter"#sname, \ | 144 | .name = "sys_enter"#sname, \ |
| 180 | .system = "syscalls", \ | 145 | .system = "syscalls", \ |
| 181 | .event = &event_syscall_enter, \ | 146 | .event = &enter_syscall_print_##sname, \ |
| 182 | .raw_init = init_enter_##sname, \ | 147 | .raw_init = init_syscall_trace, \ |
| 183 | .show_format = syscall_enter_format, \ | 148 | .show_format = syscall_enter_format, \ |
| 184 | .define_fields = syscall_enter_define_fields, \ | 149 | .define_fields = syscall_enter_define_fields, \ |
| 185 | .regfunc = reg_event_syscall_enter, \ | 150 | .regfunc = reg_event_syscall_enter, \ |
| 186 | .unregfunc = unreg_event_syscall_enter, \ | 151 | .unregfunc = unreg_event_syscall_enter, \ |
| 187 | .data = "sys"#sname, \ | 152 | .data = (void *)&__syscall_meta_##sname,\ |
| 188 | TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | 153 | TRACE_SYS_ENTER_PROFILE_INIT(sname) \ |
| 189 | } | 154 | } |
| 190 | 155 | ||
| 191 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 156 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
| 157 | static const struct syscall_metadata __syscall_meta_##sname; \ | ||
| 192 | static struct ftrace_event_call event_exit_##sname; \ | 158 | static struct ftrace_event_call event_exit_##sname; \ |
| 193 | struct trace_event exit_syscall_print_##sname = { \ | 159 | static struct trace_event exit_syscall_print_##sname = { \ |
| 194 | .trace = print_syscall_exit, \ | 160 | .trace = print_syscall_exit, \ |
| 195 | }; \ | 161 | }; \ |
| 196 | static int init_exit_##sname(void) \ | ||
| 197 | { \ | ||
| 198 | int num, id; \ | ||
| 199 | num = syscall_name_to_nr("sys"#sname); \ | ||
| 200 | if (num < 0) \ | ||
| 201 | return -ENOSYS; \ | ||
| 202 | id = register_ftrace_event(&exit_syscall_print_##sname);\ | ||
| 203 | if (!id) \ | ||
| 204 | return -ENODEV; \ | ||
| 205 | event_exit_##sname.id = id; \ | ||
| 206 | set_syscall_exit_id(num, id); \ | ||
| 207 | INIT_LIST_HEAD(&event_exit_##sname.fields); \ | ||
| 208 | return 0; \ | ||
| 209 | } \ | ||
| 210 | TRACE_SYS_EXIT_PROFILE(sname); \ | ||
| 211 | static struct ftrace_event_call __used \ | 162 | static struct ftrace_event_call __used \ |
| 212 | __attribute__((__aligned__(4))) \ | 163 | __attribute__((__aligned__(4))) \ |
| 213 | __attribute__((section("_ftrace_events"))) \ | 164 | __attribute__((section("_ftrace_events"))) \ |
| 214 | event_exit_##sname = { \ | 165 | event_exit_##sname = { \ |
| 215 | .name = "sys_exit"#sname, \ | 166 | .name = "sys_exit"#sname, \ |
| 216 | .system = "syscalls", \ | 167 | .system = "syscalls", \ |
| 217 | .event = &event_syscall_exit, \ | 168 | .event = &exit_syscall_print_##sname, \ |
| 218 | .raw_init = init_exit_##sname, \ | 169 | .raw_init = init_syscall_trace, \ |
| 219 | .show_format = syscall_exit_format, \ | 170 | .show_format = syscall_exit_format, \ |
| 220 | .define_fields = syscall_exit_define_fields, \ | 171 | .define_fields = syscall_exit_define_fields, \ |
| 221 | .regfunc = reg_event_syscall_exit, \ | 172 | .regfunc = reg_event_syscall_exit, \ |
| 222 | .unregfunc = unreg_event_syscall_exit, \ | 173 | .unregfunc = unreg_event_syscall_exit, \ |
| 223 | .data = "sys"#sname, \ | 174 | .data = (void *)&__syscall_meta_##sname,\ |
| 224 | TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | 175 | TRACE_SYS_EXIT_PROFILE_INIT(sname) \ |
| 225 | } | 176 | } |
| 226 | 177 | ||
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 2aac8a83e89b..f59604ed0ec6 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -280,6 +280,12 @@ static inline void tracepoint_synchronize_unregister(void) | |||
| 280 | * TRACE_EVENT_FN to perform any (un)registration work. | 280 | * TRACE_EVENT_FN to perform any (un)registration work. |
| 281 | */ | 281 | */ |
| 282 | 282 | ||
| 283 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) | ||
| 284 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
| 285 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
| 286 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | ||
| 287 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
| 288 | |||
| 283 | #define TRACE_EVENT(name, proto, args, struct, assign, print) \ | 289 | #define TRACE_EVENT(name, proto, args, struct, assign, print) \ |
| 284 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | 290 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
| 285 | #define TRACE_EVENT_FN(name, proto, args, struct, \ | 291 | #define TRACE_EVENT_FN(name, proto, args, struct, \ |
