diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-12-05 03:44:31 -0500 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-12-06 02:27:18 -0500 |
commit | b326e9560a28fc3e950637ef51847ed8f05c1335 (patch) | |
tree | 0804c8c4f28d4ae152d5e9205ce5a958f0d26b79 /include/linux/hw_breakpoint.h | |
parent | 2f0993e0fb663c49e4d1e02654f6203246be4817 (diff) |
hw-breakpoints: Use overflow handler instead of the event callback
struct perf_event::event callback was called when a breakpoint
triggers. But this is a rather opaque callback, pretty
tied-only to the breakpoint API and not really integrated into perf
as it triggers even when we don't overflow.
We prefer to use overflow_handler() as it fits into the perf events
rules, being called only when we overflow.
Reported-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: "K. Prasad" <prasad@linux.vnet.ibm.com>
Diffstat (limited to 'include/linux/hw_breakpoint.h')
-rw-r--r-- | include/linux/hw_breakpoint.h | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index d33096e0dbd4..4d14a384a01e 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h | |||
@@ -20,19 +20,16 @@ enum { | |||
20 | 20 | ||
21 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 21 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
22 | 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) | 23 | static inline void hw_breakpoint_init(struct perf_event_attr *attr) |
32 | { | 24 | { |
33 | attr->type = PERF_TYPE_BREAKPOINT; | 25 | attr->type = PERF_TYPE_BREAKPOINT; |
34 | attr->size = sizeof(*attr); | 26 | attr->size = sizeof(*attr); |
27 | /* | ||
28 | * As it's for in-kernel or ptrace use, we want it to be pinned | ||
29 | * and to call its callback every hits. | ||
30 | */ | ||
35 | attr->pinned = 1; | 31 | attr->pinned = 1; |
32 | attr->sample_period = 1; | ||
36 | } | 33 | } |
37 | 34 | ||
38 | static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) | 35 | static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) |
@@ -52,7 +49,7 @@ static inline int hw_breakpoint_len(struct perf_event *bp) | |||
52 | 49 | ||
53 | extern struct perf_event * | 50 | extern struct perf_event * |
54 | register_user_hw_breakpoint(struct perf_event_attr *attr, | 51 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
55 | perf_callback_t triggered, | 52 | perf_overflow_handler_t triggered, |
56 | struct task_struct *tsk); | 53 | struct task_struct *tsk); |
57 | 54 | ||
58 | /* FIXME: only change from the attr, and don't unregister */ | 55 | /* FIXME: only change from the attr, and don't unregister */ |
@@ -64,12 +61,12 @@ modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr); | |||
64 | */ | 61 | */ |
65 | extern struct perf_event * | 62 | extern struct perf_event * |
66 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | 63 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
67 | perf_callback_t triggered, | 64 | perf_overflow_handler_t triggered, |
68 | int cpu); | 65 | int cpu); |
69 | 66 | ||
70 | extern struct perf_event ** | 67 | extern struct perf_event ** |
71 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | 68 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
72 | perf_callback_t triggered); | 69 | perf_overflow_handler_t triggered); |
73 | 70 | ||
74 | extern int register_perf_hw_breakpoint(struct perf_event *bp); | 71 | extern int register_perf_hw_breakpoint(struct perf_event *bp); |
75 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); | 72 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); |
@@ -90,18 +87,18 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) | |||
90 | 87 | ||
91 | static inline struct perf_event * | 88 | static inline struct perf_event * |
92 | register_user_hw_breakpoint(struct perf_event_attr *attr, | 89 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
93 | perf_callback_t triggered, | 90 | perf_overflow_handler_t triggered, |
94 | struct task_struct *tsk) { return NULL; } | 91 | struct task_struct *tsk) { return NULL; } |
95 | static inline struct perf_event * | 92 | static inline struct perf_event * |
96 | modify_user_hw_breakpoint(struct perf_event *bp, | 93 | modify_user_hw_breakpoint(struct perf_event *bp, |
97 | struct perf_event_attr *attr) { return NULL; } | 94 | struct perf_event_attr *attr) { return NULL; } |
98 | static inline struct perf_event * | 95 | static inline struct perf_event * |
99 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | 96 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
100 | perf_callback_t triggered, | 97 | perf_overflow_handler_t triggered, |
101 | int cpu) { return NULL; } | 98 | int cpu) { return NULL; } |
102 | static inline struct perf_event ** | 99 | static inline struct perf_event ** |
103 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | 100 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
104 | perf_callback_t triggered) { return NULL; } | 101 | perf_overflow_handler_t triggered) { return NULL; } |
105 | static inline int | 102 | static inline int |
106 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | 103 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } |
107 | static inline int | 104 | static inline int |