aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-12-05 03:44:31 -0500
committerFrederic Weisbecker <fweisbec@gmail.com>2009-12-06 02:27:18 -0500
commitb326e9560a28fc3e950637ef51847ed8f05c1335 (patch)
tree0804c8c4f28d4ae152d5e9205ce5a958f0d26b79 /include/linux
parent2f0993e0fb663c49e4d1e02654f6203246be4817 (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')
-rw-r--r--include/linux/hw_breakpoint.h25
-rw-r--r--include/linux/perf_event.h13
2 files changed, 18 insertions, 20 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) \
25struct perf_event_attr name = { \
26 .type = PERF_TYPE_BREAKPOINT, \
27 .size = sizeof(name), \
28 .pinned = 1, \
29};
30
31static inline void hw_breakpoint_init(struct perf_event_attr *attr) 23static 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
38static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) 35static 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
53extern struct perf_event * 50extern struct perf_event *
54register_user_hw_breakpoint(struct perf_event_attr *attr, 51register_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 */
65extern struct perf_event * 62extern struct perf_event *
66register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, 63register_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
70extern struct perf_event ** 67extern struct perf_event **
71register_wide_hw_breakpoint(struct perf_event_attr *attr, 68register_wide_hw_breakpoint(struct perf_event_attr *attr,
72 perf_callback_t triggered); 69 perf_overflow_handler_t triggered);
73 70
74extern int register_perf_hw_breakpoint(struct perf_event *bp); 71extern int register_perf_hw_breakpoint(struct perf_event *bp);
75extern int __register_perf_hw_breakpoint(struct perf_event *bp); 72extern 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
91static inline struct perf_event * 88static inline struct perf_event *
92register_user_hw_breakpoint(struct perf_event_attr *attr, 89register_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; }
95static inline struct perf_event * 92static inline struct perf_event *
96modify_user_hw_breakpoint(struct perf_event *bp, 93modify_user_hw_breakpoint(struct perf_event *bp,
97 struct perf_event_attr *attr) { return NULL; } 94 struct perf_event_attr *attr) { return NULL; }
98static inline struct perf_event * 95static inline struct perf_event *
99register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, 96register_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; }
102static inline struct perf_event ** 99static inline struct perf_event **
103register_wide_hw_breakpoint(struct perf_event_attr *attr, 100register_wide_hw_breakpoint(struct perf_event_attr *attr,
104 perf_callback_t triggered) { return NULL; } 101 perf_overflow_handler_t triggered) { return NULL; }
105static inline int 102static inline int
106register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } 103register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
107static inline int 104static inline int
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 84bd28a0ffab..d2f2667430da 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -565,10 +565,13 @@ struct perf_pending_entry {
565 void (*func)(struct perf_pending_entry *); 565 void (*func)(struct perf_pending_entry *);
566}; 566};
567 567
568typedef void (*perf_callback_t)(struct perf_event *, void *);
569
570struct perf_sample_data; 568struct perf_sample_data;
571 569
570typedef void (*perf_callback_t)(struct perf_event *, void *);
571typedef void (*perf_overflow_handler_t)(struct perf_event *, int,
572 struct perf_sample_data *,
573 struct pt_regs *regs);
574
572/** 575/**
573 * struct perf_event - performance event kernel representation: 576 * struct perf_event - performance event kernel representation:
574 */ 577 */
@@ -660,9 +663,7 @@ struct perf_event {
660 struct pid_namespace *ns; 663 struct pid_namespace *ns;
661 u64 id; 664 u64 id;
662 665
663 void (*overflow_handler)(struct perf_event *event, 666 perf_overflow_handler_t overflow_handler;
664 int nmi, struct perf_sample_data *data,
665 struct pt_regs *regs);
666 667
667#ifdef CONFIG_EVENT_PROFILE 668#ifdef CONFIG_EVENT_PROFILE
668 struct event_filter *filter; 669 struct event_filter *filter;
@@ -779,7 +780,7 @@ extern struct perf_event *
779perf_event_create_kernel_counter(struct perf_event_attr *attr, 780perf_event_create_kernel_counter(struct perf_event_attr *attr,
780 int cpu, 781 int cpu,
781 pid_t pid, 782 pid_t pid,
782 perf_callback_t callback); 783 perf_overflow_handler_t callback);
783extern u64 perf_event_read_value(struct perf_event *event, 784extern u64 perf_event_read_value(struct perf_event *event,
784 u64 *enabled, u64 *running); 785 u64 *enabled, u64 *running);
785 786