Skip to content

Commit f7794d5

Browse files
olsajiriacmel
authored andcommitted
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 <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: David Ahern <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent de63403 commit f7794d5

File tree

4 files changed

+109
-2
lines changed

4 files changed

+109
-2
lines changed

tools/perf/util/evsel.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,106 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
13021302
return 0;
13031303
}
13041304

1305+
static int
1306+
perf_evsel__read_one(struct perf_evsel *evsel, int cpu, int thread)
1307+
{
1308+
struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread);
1309+
1310+
return perf_evsel__read(evsel, cpu, thread, count);
1311+
}
1312+
1313+
static void
1314+
perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread,
1315+
u64 val, u64 ena, u64 run)
1316+
{
1317+
struct perf_counts_values *count;
1318+
1319+
count = perf_counts(counter->counts, cpu, thread);
1320+
1321+
count->val = val;
1322+
count->ena = ena;
1323+
count->run = run;
1324+
}
1325+
1326+
static int
1327+
perf_evsel__process_group_data(struct perf_evsel *leader,
1328+
int cpu, int thread, u64 *data)
1329+
{
1330+
u64 read_format = leader->attr.read_format;
1331+
struct sample_read_value *v;
1332+
u64 nr, ena = 0, run = 0, i;
1333+
1334+
nr = *data++;
1335+
1336+
if (nr != (u64) leader->nr_members)
1337+
return -EINVAL;
1338+
1339+
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1340+
ena = *data++;
1341+
1342+
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1343+
run = *data++;
1344+
1345+
v = (struct sample_read_value *) data;
1346+
1347+
perf_evsel__set_count(leader, cpu, thread,
1348+
v[0].value, ena, run);
1349+
1350+
for (i = 1; i < nr; i++) {
1351+
struct perf_evsel *counter;
1352+
1353+
counter = perf_evlist__id2evsel(leader->evlist, v[i].id);
1354+
if (!counter)
1355+
return -EINVAL;
1356+
1357+
perf_evsel__set_count(counter, cpu, thread,
1358+
v[i].value, ena, run);
1359+
}
1360+
1361+
return 0;
1362+
}
1363+
1364+
static int
1365+
perf_evsel__read_group(struct perf_evsel *leader, int cpu, int thread)
1366+
{
1367+
struct perf_stat_evsel *ps = leader->priv;
1368+
u64 read_format = leader->attr.read_format;
1369+
int size = perf_evsel__read_size(leader);
1370+
u64 *data = ps->group_data;
1371+
1372+
if (!(read_format & PERF_FORMAT_ID))
1373+
return -EINVAL;
1374+
1375+
if (!perf_evsel__is_group_leader(leader))
1376+
return -EINVAL;
1377+
1378+
if (!data) {
1379+
data = zalloc(size);
1380+
if (!data)
1381+
return -ENOMEM;
1382+
1383+
ps->group_data = data;
1384+
}
1385+
1386+
if (FD(leader, cpu, thread) < 0)
1387+
return -EINVAL;
1388+
1389+
if (readn(FD(leader, cpu, thread), data, size) <= 0)
1390+
return -errno;
1391+
1392+
return perf_evsel__process_group_data(leader, cpu, thread, data);
1393+
}
1394+
1395+
int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread)
1396+
{
1397+
u64 read_format = evsel->attr.read_format;
1398+
1399+
if (read_format & PERF_FORMAT_GROUP)
1400+
return perf_evsel__read_group(evsel, cpu, thread);
1401+
else
1402+
return perf_evsel__read_one(evsel, cpu, thread);
1403+
}
1404+
13051405
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
13061406
int cpu, int thread, bool scale)
13071407
{

tools/perf/util/evsel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1,
299299
int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
300300
struct perf_counts_values *count);
301301

302+
int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread);
303+
302304
int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
303305
int cpu, int thread, bool scale);
304306

tools/perf/util/stat.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
128128

129129
static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
130130
{
131+
struct perf_stat_evsel *ps = evsel->priv;
132+
133+
if (ps)
134+
free(ps->group_data);
131135
zfree(&evsel->priv);
132136
}
133137

tools/perf/util/stat.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ enum perf_stat_evsel_id {
2828
};
2929

3030
struct perf_stat_evsel {
31-
struct stats res_stats[3];
32-
enum perf_stat_evsel_id id;
31+
struct stats res_stats[3];
32+
enum perf_stat_evsel_id id;
33+
u64 *group_data;
3334
};
3435

3536
enum aggr_mode {

0 commit comments

Comments
 (0)