Skip to content

Commit

Permalink
perf stat: Make stats work over the thread dimension
Browse files Browse the repository at this point in the history
Now that we have space for thread dimension counts, let's store it.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1435310967-14570-7-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Jun 26, 2015
1 parent a8e0232 commit a6fa003
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 34 deletions.
32 changes: 18 additions & 14 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,12 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
zfree(&evsel->priv);
}

static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
int ncpus, int nthreads)
{
struct perf_counts *counts;

counts = perf_counts__new(perf_evsel__nr_cpus(evsel));
counts = perf_counts__new(ncpus, nthreads);
if (counts)
evsel->prev_raw_counts = counts;

Expand All @@ -197,11 +198,14 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist)
static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
{
struct perf_evsel *evsel;
int nthreads = thread_map__nr(evsel_list->threads);

evlist__for_each(evlist, evsel) {
int ncpus = perf_evsel__nr_cpus(evsel);

if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
(alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
(alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
goto out_free;
}

Expand Down Expand Up @@ -294,7 +298,7 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
return 0;
}

static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
struct perf_counts_values *count)
{
struct perf_counts_values *aggr = &evsel->counts->aggr;
Expand All @@ -314,9 +318,9 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
case AGGR_SOCKET:
case AGGR_NONE:
if (!evsel->snapshot)
perf_evsel__compute_deltas(evsel, cpu, count);
perf_evsel__compute_deltas(evsel, cpu, thread, count);
perf_counts_values__scale(count, scale, NULL);
*perf_counts(evsel->counts, cpu) = *count;
*perf_counts(evsel->counts, cpu, thread) = *count;
if (aggr_mode == AGGR_NONE)
perf_stat__update_shadow_stats(evsel, count->values, cpu);
break;
Expand Down Expand Up @@ -352,7 +356,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
return -1;

if (!counter->snapshot)
perf_evsel__compute_deltas(counter, -1, aggr);
perf_evsel__compute_deltas(counter, -1, -1, aggr);
perf_counts_values__scale(aggr, scale, &counter->counts->scaled);

for (i = 0; i < 3; i++)
Expand Down Expand Up @@ -805,9 +809,9 @@ static void print_aggr(char *prefix)
s2 = aggr_get_id(evsel_list->cpus, cpu2);
if (s2 != id)
continue;
val += perf_counts(counter->counts, cpu)->val;
ena += perf_counts(counter->counts, cpu)->ena;
run += perf_counts(counter->counts, cpu)->run;
val += perf_counts(counter->counts, cpu, 0)->val;
ena += perf_counts(counter->counts, cpu, 0)->ena;
run += perf_counts(counter->counts, cpu, 0)->run;
nr++;
}
if (prefix)
Expand Down Expand Up @@ -915,9 +919,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
int cpu;

for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
val = perf_counts(counter->counts, cpu)->val;
ena = perf_counts(counter->counts, cpu)->ena;
run = perf_counts(counter->counts, cpu)->run;
val = perf_counts(counter->counts, cpu, 0)->val;
ena = perf_counts(counter->counts, cpu, 0)->ena;
run = perf_counts(counter->counts, cpu, 0)->run;

if (prefix)
fprintf(output, "%s", prefix);
Expand Down
6 changes: 3 additions & 3 deletions tools/perf/tests/openat-syscall-all-cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ int test__openat_syscall_event_on_all_cpus(void)
* we use the auto allocation it will allocate just for 1 cpu,
* as we start by cpu 0.
*/
if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
if (perf_evsel__alloc_counts(evsel, cpus->nr, 1) < 0) {
pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
goto out_close_fd;
}
Expand All @@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void)
}

expected = nr_openat_calls + cpu;
if (perf_counts(evsel->counts, cpu)->val != expected) {
if (perf_counts(evsel->counts, cpu, 0)->val != expected) {
pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
expected, cpus->map[cpu], perf_counts(evsel->counts, cpu)->val);
expected, cpus->map[cpu], perf_counts(evsel->counts, cpu, 0)->val);
err = -1;
}
}
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/tests/openat-syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ int test__openat_syscall_event(void)
goto out_close_fd;
}

if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
if (perf_counts(evsel->counts, 0, 0)->val != nr_openat_calls) {
pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
nr_openat_calls, perf_counts(evsel->counts, 0)->val);
nr_openat_calls, perf_counts(evsel->counts, 0, 0)->val);
goto out_close_fd;
}

Expand Down
12 changes: 6 additions & 6 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
free(evsel);
}

void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread,
struct perf_counts_values *count)
{
struct perf_counts_values tmp;
Expand All @@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
tmp = evsel->prev_raw_counts->aggr;
evsel->prev_raw_counts->aggr = *count;
} else {
tmp = *perf_counts(evsel->prev_raw_counts, cpu);
*perf_counts(evsel->prev_raw_counts, cpu) = *count;
tmp = *perf_counts(evsel->prev_raw_counts, cpu, thread);
*perf_counts(evsel->prev_raw_counts, cpu, thread) = *count;
}

count->val = count->val - tmp.val;
Expand Down Expand Up @@ -964,15 +964,15 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
if (FD(evsel, cpu, thread) < 0)
return -EINVAL;

if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1) < 0)
if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0)
return -ENOMEM;

if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0)
return -errno;

perf_evsel__compute_deltas(evsel, cpu, &count);
perf_evsel__compute_deltas(evsel, cpu, thread, &count);
perf_counts_values__scale(&count, scale, NULL);
*perf_counts(evsel->counts, cpu) = count;
*perf_counts(evsel->counts, cpu, thread) = count;
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/evsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
void perf_counts_values__scale(struct perf_counts_values *count,
bool scale, s8 *pscaled);

void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread,
struct perf_counts_values *count);

int perf_evsel__object_config(size_t object_size,
Expand Down
8 changes: 4 additions & 4 deletions tools/perf/util/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
}
}

struct perf_counts *perf_counts__new(int ncpus)
struct perf_counts *perf_counts__new(int ncpus, int nthreads)
{
struct perf_counts *counts = zalloc(sizeof(*counts));

if (counts) {
struct xyarray *cpu;

cpu = xyarray__new(ncpus, 1, sizeof(struct perf_counts_values));
cpu = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
if (!cpu) {
free(counts);
return NULL;
Expand Down Expand Up @@ -132,9 +132,9 @@ void perf_evsel__reset_counts(struct perf_evsel *evsel)
perf_counts__reset(evsel->counts);
}

int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
{
evsel->counts = perf_counts__new(ncpus);
evsel->counts = perf_counts__new(ncpus, nthreads);
return evsel->counts != NULL ? 0 : -ENOMEM;
}

Expand Down
8 changes: 4 additions & 4 deletions tools/perf/util/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ struct perf_counts {
};

static inline struct perf_counts_values*
perf_counts(struct perf_counts *counts, int cpu)
perf_counts(struct perf_counts *counts, int cpu, int thread)
{
return xyarray__entry(counts->cpu, cpu, 0);
return xyarray__entry(counts->cpu, cpu, thread);
}

void update_stats(struct stats *stats, u64 val);
Expand Down Expand Up @@ -86,10 +86,10 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
double avg, int cpu, enum aggr_mode aggr);

struct perf_counts *perf_counts__new(int ncpus);
struct perf_counts *perf_counts__new(int ncpus, int nthreads);
void perf_counts__delete(struct perf_counts *counts);

void perf_evsel__reset_counts(struct perf_evsel *evsel);
int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
void perf_evsel__free_counts(struct perf_evsel *evsel);
#endif

0 comments on commit a6fa003

Please sign in to comment.