aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2010-05-11 10:19:10 -0400
committerIngo Molnar <mingo@elte.hu>2010-05-11 11:08:24 -0400
commit96c21a460a37880abfbc8445d5b098dbab958a29 (patch)
tree57b6ae2ecb8713b720fb5ee86ebbf3d1b2638856 /kernel/perf_event.c
parent050735b08ca8a016bbace4445fa025b88fee770b (diff)
perf: Fix exit() vs event-groups
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>
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index c97e82518403..a4fa381db3c2 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -255,6 +255,18 @@ static void update_event_times(struct perf_event *event)
255 event->total_time_running = run_end - event->tstamp_running; 255 event->total_time_running = run_end - event->tstamp_running;
256} 256}
257 257
258/*
259 * Update total_time_enabled and total_time_running for all events in a group.
260 */
261static void update_group_times(struct perf_event *leader)
262{
263 struct perf_event *event;
264
265 update_event_times(leader);
266 list_for_each_entry(event, &leader->sibling_list, group_entry)
267 update_event_times(event);
268}
269
258static struct list_head * 270static struct list_head *
259ctx_group_list(struct perf_event *event, struct perf_event_context *ctx) 271ctx_group_list(struct perf_event *event, struct perf_event_context *ctx)
260{ 272{
@@ -320,7 +332,7 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
320 if (event->group_leader != event) 332 if (event->group_leader != event)
321 event->group_leader->nr_siblings--; 333 event->group_leader->nr_siblings--;
322 334
323 update_event_times(event); 335 update_group_times(event);
324 336
325 /* 337 /*
326 * If event was in error state, then keep it 338 * If event was in error state, then keep it
@@ -502,18 +514,6 @@ retry:
502} 514}
503 515
504/* 516/*
505 * Update total_time_enabled and total_time_running for all events in a group.
506 */
507static void update_group_times(struct perf_event *leader)
508{
509 struct perf_event *event;
510
511 update_event_times(leader);
512 list_for_each_entry(event, &leader->sibling_list, group_entry)
513 update_event_times(event);
514}
515
516/*
517 * Cross CPU call to disable a performance event 517 * Cross CPU call to disable a performance event
518 */ 518 */
519static void __perf_event_disable(void *info) 519static void __perf_event_disable(void *info)