Skip to content

Commit 55ab378

Browse files
perf tools: pushing driver configuration down to the kernel
Now that PMU specific driver configuration are queued in evsel::drv_config_terms, all we need to do is re-use the current ioctl() mechanism to push down the information to the kernel driver. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
1 parent 6a453d5 commit 55ab378

5 files changed

Lines changed: 71 additions & 0 deletions

File tree

tools/perf/builtin-record.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ static int record__open(struct record *rec)
276276
struct perf_evlist *evlist = rec->evlist;
277277
struct perf_session *session = rec->session;
278278
struct record_opts *opts = &rec->opts;
279+
struct perf_evsel_config_term *err_term;
279280
int rc = 0;
280281

281282
perf_evlist__config(evlist, opts);
@@ -305,6 +306,14 @@ static int record__open(struct record *rec)
305306
goto out;
306307
}
307308

309+
if (perf_evlist__apply_drv_configs(evlist, &pos, &err_term)) {
310+
error("failed to set config \"%s\" on event %s with %d (%s)\n",
311+
err_term->val.drv_cfg, perf_evsel__name(pos), errno,
312+
strerror_r(errno, msg, sizeof(msg)));
313+
rc = -1;
314+
goto out;
315+
}
316+
308317
if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
309318
opts->auxtrace_mmap_pages,
310319
opts->auxtrace_snapshot_mode) < 0) {

tools/perf/util/evlist.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,30 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
12471247
return err;
12481248
}
12491249

1250+
int perf_evlist__apply_drv_configs(struct perf_evlist *evlist,
1251+
struct perf_evsel **err_evsel,
1252+
struct perf_evsel_config_term **err_term)
1253+
{
1254+
struct perf_evsel *evsel;
1255+
int err = 0;
1256+
const int ncpus = cpu_map__nr(evlist->cpus),
1257+
nthreads = thread_map__nr(evlist->threads);
1258+
1259+
evlist__for_each(evlist, evsel) {
1260+
if (list_empty(&evsel->drv_config_terms))
1261+
continue;
1262+
1263+
err = perf_evsel__apply_drv_configs(evsel, ncpus,
1264+
nthreads, err_term);
1265+
if (err) {
1266+
*err_evsel = evsel;
1267+
break;
1268+
}
1269+
}
1270+
1271+
return err;
1272+
}
1273+
12501274
int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
12511275
{
12521276
struct perf_evsel *evsel;

tools/perf/util/evlist.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus,
163163
struct thread_map *threads);
164164
int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target);
165165
int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel);
166+
int perf_evlist__apply_drv_configs(struct perf_evlist *evlist,
167+
struct perf_evsel **err_evsel,
168+
struct perf_evsel_config_term **term);
166169

167170
void __perf_evlist__set_leader(struct list_head *list);
168171
void perf_evlist__set_leader(struct perf_evlist *evlist);

tools/perf/util/evsel.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,27 @@ int perf_evsel__append_filter(struct perf_evsel *evsel,
982982
return -1;
983983
}
984984

985+
int perf_evsel__apply_drv_configs(struct perf_evsel *evsel,
986+
int ncpus, int nthreads,
987+
struct perf_evsel_config_term **err_term)
988+
{
989+
int err = 0;
990+
struct perf_evsel_config_term *term;
991+
992+
list_for_each_entry(term, &evsel->drv_config_terms, list) {
993+
err = perf_evsel__run_ioctl(evsel, ncpus, nthreads,
994+
PERF_EVENT_IOC_SET_DRV_CONFIGS,
995+
(void *)term->val.drv_cfg);
996+
997+
if (err) {
998+
*err_term = term;
999+
break;
1000+
}
1001+
}
1002+
1003+
return err;
1004+
}
1005+
9851006
int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)
9861007
{
9871008
return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
@@ -1044,6 +1065,16 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
10441065
}
10451066
}
10461067

1068+
static void perf_evsel__free_drv_config_terms(struct perf_evsel *evsel)
1069+
{
1070+
struct perf_evsel_config_term *term, *h;
1071+
1072+
list_for_each_entry_safe(term, h, &evsel->drv_config_terms, list) {
1073+
list_del(&term->list);
1074+
free(term);
1075+
}
1076+
}
1077+
10471078
void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
10481079
{
10491080
int cpu, thread;
@@ -1065,6 +1096,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
10651096
perf_evsel__free_fd(evsel);
10661097
perf_evsel__free_id(evsel);
10671098
perf_evsel__free_config_terms(evsel);
1099+
perf_evsel__free_drv_config_terms(evsel);
10681100
close_cgroup(evsel->cgrp);
10691101
cpu_map__put(evsel->cpus);
10701102
cpu_map__put(evsel->own_cpus);

tools/perf/util/evsel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ int perf_evsel__append_filter(struct perf_evsel *evsel,
231231
const char *op, const char *filter);
232232
int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
233233
const char *filter);
234+
int perf_evsel__apply_drv_configs(struct perf_evsel *evsel,
235+
int ncpus, int nthreads,
236+
struct perf_evsel_config_term **err_term);
234237
int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads);
235238
int perf_evsel__disable(struct perf_evsel *evsel);
236239

0 commit comments

Comments
 (0)