Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6fa0038 authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo
Browse files

perf stat: Make stats work over the thread dimension



Now that we have space for thread dimension counts, let's store it.

Signed-off-by: default avatarJiri 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent a8e02324
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -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;

@@ -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;
	}

@@ -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;
@@ -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;
@@ -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++)
@@ -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)
@@ -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);
+3 −3
Original line number Diff line number Diff line
@@ -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;
	}
@@ -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;
		}
	}
+2 −2
Original line number Diff line number Diff line
@@ -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;
	}

+6 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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,
Loading