aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_counter.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-07-24 08:42:10 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-02 07:47:54 -0400
commite53c0994709166b111fbe9162d1a16ece7dfc45b (patch)
tree5182e8f91bffae8fcbe05a9b86e761f84b0f079e /kernel/perf_counter.c
parent470a1396c25c27b4aff08b14d5c9cd9b3da15e09 (diff)
perf_counter: Collapse inherit on read()
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>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r--kernel/perf_counter.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 950931041954..48471d75ae01 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1688,6 +1688,18 @@ static int perf_release(struct inode *inode, struct file *file)
1688 return 0; 1688 return 0;
1689} 1689}
1690 1690
1691static u64 perf_counter_read_tree(struct perf_counter *counter)
1692{
1693 struct perf_counter *child;
1694 u64 total = 0;
1695
1696 total += perf_counter_read(counter);
1697 list_for_each_entry(child, &counter->child_list, child_list)
1698 total += perf_counter_read(child);
1699
1700 return total;
1701}
1702
1691/* 1703/*
1692 * Read the performance counter - simple non blocking version for now 1704 * Read the performance counter - simple non blocking version for now
1693 */ 1705 */
@@ -1707,7 +1719,7 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count)
1707 1719
1708 WARN_ON_ONCE(counter->ctx->parent_ctx); 1720 WARN_ON_ONCE(counter->ctx->parent_ctx);
1709 mutex_lock(&counter->child_mutex); 1721 mutex_lock(&counter->child_mutex);
1710 values[0] = perf_counter_read(counter); 1722 values[0] = perf_counter_read_tree(counter);
1711 n = 1; 1723 n = 1;
1712 if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 1724 if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1713 values[n++] = counter->total_time_enabled + 1725 values[n++] = counter->total_time_enabled +