mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-06 06:35:12 +00:00
perf evsel: Add read_counter()
Add perf_evsel__read_counter() to read single or group counter. After calling this function the counter's evsel::counts struct is filled with values for the counter and member of its group if there are any. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/20170726120206.9099-3-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
de63403bfd
commit
f7794d5254
4 changed files with 109 additions and 2 deletions
|
@ -1302,6 +1302,106 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
perf_evsel__read_one(struct perf_evsel *evsel, int cpu, int thread)
|
||||||
|
{
|
||||||
|
struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread);
|
||||||
|
|
||||||
|
return perf_evsel__read(evsel, cpu, thread, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread,
|
||||||
|
u64 val, u64 ena, u64 run)
|
||||||
|
{
|
||||||
|
struct perf_counts_values *count;
|
||||||
|
|
||||||
|
count = perf_counts(counter->counts, cpu, thread);
|
||||||
|
|
||||||
|
count->val = val;
|
||||||
|
count->ena = ena;
|
||||||
|
count->run = run;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
perf_evsel__process_group_data(struct perf_evsel *leader,
|
||||||
|
int cpu, int thread, u64 *data)
|
||||||
|
{
|
||||||
|
u64 read_format = leader->attr.read_format;
|
||||||
|
struct sample_read_value *v;
|
||||||
|
u64 nr, ena = 0, run = 0, i;
|
||||||
|
|
||||||
|
nr = *data++;
|
||||||
|
|
||||||
|
if (nr != (u64) leader->nr_members)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
|
||||||
|
ena = *data++;
|
||||||
|
|
||||||
|
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
|
||||||
|
run = *data++;
|
||||||
|
|
||||||
|
v = (struct sample_read_value *) data;
|
||||||
|
|
||||||
|
perf_evsel__set_count(leader, cpu, thread,
|
||||||
|
v[0].value, ena, run);
|
||||||
|
|
||||||
|
for (i = 1; i < nr; i++) {
|
||||||
|
struct perf_evsel *counter;
|
||||||
|
|
||||||
|
counter = perf_evlist__id2evsel(leader->evlist, v[i].id);
|
||||||
|
if (!counter)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
perf_evsel__set_count(counter, cpu, thread,
|
||||||
|
v[i].value, ena, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
perf_evsel__read_group(struct perf_evsel *leader, int cpu, int thread)
|
||||||
|
{
|
||||||
|
struct perf_stat_evsel *ps = leader->priv;
|
||||||
|
u64 read_format = leader->attr.read_format;
|
||||||
|
int size = perf_evsel__read_size(leader);
|
||||||
|
u64 *data = ps->group_data;
|
||||||
|
|
||||||
|
if (!(read_format & PERF_FORMAT_ID))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!perf_evsel__is_group_leader(leader))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = zalloc(size);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ps->group_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD(leader, cpu, thread) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (readn(FD(leader, cpu, thread), data, size) <= 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return perf_evsel__process_group_data(leader, cpu, thread, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread)
|
||||||
|
{
|
||||||
|
u64 read_format = evsel->attr.read_format;
|
||||||
|
|
||||||
|
if (read_format & PERF_FORMAT_GROUP)
|
||||||
|
return perf_evsel__read_group(evsel, cpu, thread);
|
||||||
|
else
|
||||||
|
return perf_evsel__read_one(evsel, cpu, thread);
|
||||||
|
}
|
||||||
|
|
||||||
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
|
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
|
||||||
int cpu, int thread, bool scale)
|
int cpu, int thread, bool scale)
|
||||||
{
|
{
|
||||||
|
|
|
@ -299,6 +299,8 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1,
|
||||||
int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
|
int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
|
||||||
struct perf_counts_values *count);
|
struct perf_counts_values *count);
|
||||||
|
|
||||||
|
int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread);
|
||||||
|
|
||||||
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
|
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
|
||||||
int cpu, int thread, bool scale);
|
int cpu, int thread, bool scale);
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,10 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
|
||||||
|
|
||||||
static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
|
static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
|
||||||
{
|
{
|
||||||
|
struct perf_stat_evsel *ps = evsel->priv;
|
||||||
|
|
||||||
|
if (ps)
|
||||||
|
free(ps->group_data);
|
||||||
zfree(&evsel->priv);
|
zfree(&evsel->priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum perf_stat_evsel_id {
|
||||||
struct perf_stat_evsel {
|
struct perf_stat_evsel {
|
||||||
struct stats res_stats[3];
|
struct stats res_stats[3];
|
||||||
enum perf_stat_evsel_id id;
|
enum perf_stat_evsel_id id;
|
||||||
|
u64 *group_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum aggr_mode {
|
enum aggr_mode {
|
||||||
|
|
Loading…
Add table
Reference in a new issue