Skip to content

Commit

Permalink
perf: Fix exit() vs event-groups
Browse files Browse the repository at this point in the history
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>
Cc: <stable@kernel.org> # .34.x
LKML-Reference: <1273588935.1810.6.camel@laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed May 11, 2010
1 parent 050735b commit 96c21a4
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,18 @@ static void update_event_times(struct perf_event *event)
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)
{
Expand Down Expand Up @@ -320,7 +332,7 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
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
Expand Down Expand Up @@ -501,18 +513,6 @@ static void perf_event_remove_from_context(struct perf_event *event)
raw_spin_unlock_irq(&ctx->lock);
}

/*
* 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
*/
Expand Down

0 comments on commit 96c21a4

Please sign in to comment.