Skip to content

Commit

Permalink
perf_counter: Collapse inherit on read()
Browse files Browse the repository at this point in the history
Currently the counter value returned by read() is the value of
the parent counter, to which child counters are only fed back
on child exit.

Thus read() can return rather erratic (and meaningless) numbers
depending on the state of the child processes.

Change this by always iterating the full child hierarchy on
read() and sum all counters.

Suggested-by: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Aug 2, 2009
1 parent 470a139 commit e53c099
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion kernel/perf_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,18 @@ static int perf_release(struct inode *inode, struct file *file)
return 0;
}

static u64 perf_counter_read_tree(struct perf_counter *counter)
{
struct perf_counter *child;
u64 total = 0;

total += perf_counter_read(counter);
list_for_each_entry(child, &counter->child_list, child_list)
total += perf_counter_read(child);

return total;
}

/*
* Read the performance counter - simple non blocking version for now
*/
Expand All @@ -1707,7 +1719,7 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count)

WARN_ON_ONCE(counter->ctx->parent_ctx);
mutex_lock(&counter->child_mutex);
values[0] = perf_counter_read(counter);
values[0] = perf_counter_read_tree(counter);
n = 1;
if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
values[n++] = counter->total_time_enabled +
Expand Down

0 comments on commit e53c099

Please sign in to comment.