| From 96c21a460a37880abfbc8445d5b098dbab958a29 Mon Sep 17 00:00:00 2001 |
| From: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Date: Tue, 11 May 2010 16:19:10 +0200 |
| Subject: perf: Fix exit() vs event-groups |
| |
| From: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| |
| commit 96c21a460a37880abfbc8445d5b098dbab958a29 upstream. |
| |
| Corey reported that the value scale times of group siblings are not |
| updated when the monitored task dies. |
| |
| The problem appears to be that we only update the group leader's |
| time values, fix it by updating the whole group. |
| |
| Reported-by: Corey Ashford <cjashfor@linux.vnet.ibm.com> |
| Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Cc: Paul Mackerras <paulus@samba.org> |
| Cc: Mike Galbraith <efault@gmx.de> |
| Cc: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Cc: Frederic Weisbecker <fweisbec@gmail.com> |
| LKML-Reference: <1273588935.1810.6.camel@laptop> |
| Signed-off-by: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| kernel/perf_event.c | 26 +++++++++++++------------- |
| 1 file changed, 13 insertions(+), 13 deletions(-) |
| |
| --- a/kernel/perf_event.c |
| +++ b/kernel/perf_event.c |
| @@ -262,6 +262,18 @@ static void update_event_times(struct pe |
| event->total_time_running = run_end - event->tstamp_running; |
| } |
| |
| +/* |
| + * Update total_time_enabled and total_time_running for all events in a group. |
| + */ |
| +static void update_group_times(struct perf_event *leader) |
| +{ |
| + struct perf_event *event; |
| + |
| + update_event_times(leader); |
| + list_for_each_entry(event, &leader->sibling_list, group_entry) |
| + update_event_times(event); |
| +} |
| + |
| static struct list_head * |
| ctx_group_list(struct perf_event *event, struct perf_event_context *ctx) |
| { |
| @@ -327,7 +339,7 @@ list_del_event(struct perf_event *event, |
| if (event->group_leader != event) |
| event->group_leader->nr_siblings--; |
| |
| - update_event_times(event); |
| + update_group_times(event); |
| |
| /* |
| * If event was in error state, then keep it |
| @@ -509,18 +521,6 @@ retry: |
| } |
| |
| /* |
| - * Update total_time_enabled and total_time_running for all events in a group. |
| - */ |
| -static void update_group_times(struct perf_event *leader) |
| -{ |
| - struct perf_event *event; |
| - |
| - update_event_times(leader); |
| - list_for_each_entry(event, &leader->sibling_list, group_entry) |
| - update_event_times(event); |
| -} |
| - |
| -/* |
| * Cross CPU call to disable a performance event |
| */ |
| static void __perf_event_disable(void *info) |