Skip to content

Commit

Permalink
perf: Fix event scaling for inherited counters
Browse files Browse the repository at this point in the history
Properly account the full hierarchy of counters for both the
count (we already did so) and the scale times (new).

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <20091120212509.153379276@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Nov 21, 2009
1 parent 2b8988c commit 59ed446
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 23 deletions.
3 changes: 2 additions & 1 deletion include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,
int cpu,
pid_t pid,
perf_callback_t callback);
extern u64 perf_event_read_value(struct perf_event *event);
extern u64 perf_event_read_value(struct perf_event *event,
u64 *enabled, u64 *running);

struct perf_sample_data {
u64 type;
Expand Down
48 changes: 26 additions & 22 deletions kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -1774,14 +1774,25 @@ static int perf_event_read_size(struct perf_event *event)
return size;
}

u64 perf_event_read_value(struct perf_event *event)
u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
{
struct perf_event *child;
u64 total = 0;

*enabled = 0;
*running = 0;

total += perf_event_read(event);
list_for_each_entry(child, &event->child_list, child_list)
*enabled += event->total_time_enabled +
atomic64_read(&event->child_total_time_enabled);
*running += event->total_time_running +
atomic64_read(&event->child_total_time_running);

list_for_each_entry(child, &event->child_list, child_list) {
total += perf_event_read(child);
*enabled += child->total_time_enabled;
*running += child->total_time_running;
}

return total;
}
Expand All @@ -1793,19 +1804,15 @@ static int perf_event_read_group(struct perf_event *event,
struct perf_event *leader = event->group_leader, *sub;
int n = 0, size = 0, ret = 0;
u64 values[5];
u64 count;
u64 count, enabled, running;

count = perf_event_read_value(leader);
count = perf_event_read_value(leader, &enabled, &running);

values[n++] = 1 + leader->nr_siblings;
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
values[n++] = leader->total_time_enabled +
atomic64_read(&leader->child_total_time_enabled);
}
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
values[n++] = leader->total_time_running +
atomic64_read(&leader->child_total_time_running);
}
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
values[n++] = enabled;
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
values[n++] = running;
values[n++] = count;
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(leader);
Expand All @@ -1820,7 +1827,7 @@ static int perf_event_read_group(struct perf_event *event,
list_for_each_entry(sub, &leader->sibling_list, group_entry) {
n = 0;

values[n++] = perf_event_read_value(sub);
values[n++] = perf_event_read_value(sub, &enabled, &running);
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(sub);

Expand All @@ -1838,18 +1845,15 @@ static int perf_event_read_group(struct perf_event *event,
static int perf_event_read_one(struct perf_event *event,
u64 read_format, char __user *buf)
{
u64 enabled, running;
u64 values[4];
int n = 0;

values[n++] = perf_event_read_value(event);
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
values[n++] = event->total_time_enabled +
atomic64_read(&event->child_total_time_enabled);
}
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
values[n++] = event->total_time_running +
atomic64_read(&event->child_total_time_running);
}
values[n++] = perf_event_read_value(event, &enabled, &running);
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
values[n++] = enabled;
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
values[n++] = running;
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(event);

Expand Down

0 comments on commit 59ed446

Please sign in to comment.