diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-11-26 07:49:04 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-11-26 09:00:59 -0500 |
| commit | ee6dcfa40a50fe12a3ae0fb4d2653c66c3ed6556 (patch) | |
| tree | e77ac01a6bf2106f7a2c22f00e43cb2960d72ba5 | |
| parent | cc2067a51424dd25c10c1b1230b4222d8baec94d (diff) | |
perf: Fix the software context switch counter
Stephane noticed that because the perf_sw_event() call is inside the
perf_event_task_sched_out() call it won't get called unless we
have a per-task counter.
Reported-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | include/linux/perf_event.h | 29 | ||||
| -rw-r--r-- | kernel/perf_event.c | 2 |
2 files changed, 15 insertions, 16 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 142e3d6042c7..de2c41758e29 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -909,20 +909,6 @@ extern int perf_num_counters(void); | |||
| 909 | extern const char *perf_pmu_name(void); | 909 | extern const char *perf_pmu_name(void); |
| 910 | extern void __perf_event_task_sched_in(struct task_struct *task); | 910 | extern void __perf_event_task_sched_in(struct task_struct *task); |
| 911 | extern void __perf_event_task_sched_out(struct task_struct *task, struct task_struct *next); | 911 | extern void __perf_event_task_sched_out(struct task_struct *task, struct task_struct *next); |
| 912 | |||
| 913 | extern atomic_t perf_task_events; | ||
| 914 | |||
| 915 | static inline void perf_event_task_sched_in(struct task_struct *task) | ||
| 916 | { | ||
| 917 | COND_STMT(&perf_task_events, __perf_event_task_sched_in(task)); | ||
| 918 | } | ||
| 919 | |||
| 920 | static inline | ||
| 921 | void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next) | ||
| 922 | { | ||
| 923 | COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next)); | ||
| 924 | } | ||
| 925 | |||
| 926 | extern int perf_event_init_task(struct task_struct *child); | 912 | extern int perf_event_init_task(struct task_struct *child); |
| 927 | extern void perf_event_exit_task(struct task_struct *child); | 913 | extern void perf_event_exit_task(struct task_struct *child); |
| 928 | extern void perf_event_free_task(struct task_struct *task); | 914 | extern void perf_event_free_task(struct task_struct *task); |
| @@ -1031,6 +1017,21 @@ have_event: | |||
| 1031 | __perf_sw_event(event_id, nr, nmi, regs, addr); | 1017 | __perf_sw_event(event_id, nr, nmi, regs, addr); |
| 1032 | } | 1018 | } |
| 1033 | 1019 | ||
| 1020 | extern atomic_t perf_task_events; | ||
| 1021 | |||
| 1022 | static inline void perf_event_task_sched_in(struct task_struct *task) | ||
| 1023 | { | ||
| 1024 | COND_STMT(&perf_task_events, __perf_event_task_sched_in(task)); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | static inline | ||
| 1028 | void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next) | ||
| 1029 | { | ||
| 1030 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); | ||
| 1031 | |||
| 1032 | COND_STMT(&perf_task_events, __perf_event_task_sched_out(task, next)); | ||
| 1033 | } | ||
| 1034 | |||
| 1034 | extern void perf_event_mmap(struct vm_area_struct *vma); | 1035 | extern void perf_event_mmap(struct vm_area_struct *vma); |
| 1035 | extern struct perf_guest_info_callbacks *perf_guest_cbs; | 1036 | extern struct perf_guest_info_callbacks *perf_guest_cbs; |
| 1036 | extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); | 1037 | extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks); |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index f365dd8ef8b0..eac7e3364335 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -1287,8 +1287,6 @@ void __perf_event_task_sched_out(struct task_struct *task, | |||
| 1287 | { | 1287 | { |
| 1288 | int ctxn; | 1288 | int ctxn; |
| 1289 | 1289 | ||
| 1290 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); | ||
| 1291 | |||
| 1292 | for_each_task_context_nr(ctxn) | 1290 | for_each_task_context_nr(ctxn) |
| 1293 | perf_event_context_sched_out(task, ctxn, next); | 1291 | perf_event_context_sched_out(task, ctxn, next); |
| 1294 | } | 1292 | } |
