• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drv_configs.h: Interface to apply PMU specific configuration
3  * Copyright (c) 2016-2018, Linaro Ltd.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  */
15 
16 #include "drv_configs.h"
17 #include "evlist.h"
18 #include "evsel.h"
19 #include "pmu.h"
20 #include <errno.h>
21 
22 static int
perf_evsel__apply_drv_configs(struct perf_evsel * evsel,struct perf_evsel_config_term ** err_term)23 perf_evsel__apply_drv_configs(struct perf_evsel *evsel,
24 			      struct perf_evsel_config_term **err_term)
25 {
26 	bool found = false;
27 	int err = 0;
28 	struct perf_evsel_config_term *term;
29 	struct perf_pmu *pmu = NULL;
30 
31 	while ((pmu = perf_pmu__scan(pmu)) != NULL)
32 		if (pmu->type == evsel->attr.type) {
33 			found = true;
34 			break;
35 		}
36 
37 	list_for_each_entry(term, &evsel->config_terms, list) {
38 		if (term->type != PERF_EVSEL__CONFIG_TERM_DRV_CFG)
39 			continue;
40 
41 		/*
42 		 * We have a configuration term, report an error if we
43 		 * can't find the PMU or if the PMU driver doesn't support
44 		 * cmd line driver configuration.
45 		 */
46 		if (!found || !pmu->set_drv_config) {
47 			err = -EINVAL;
48 			*err_term = term;
49 			break;
50 		}
51 
52 		err = pmu->set_drv_config(term);
53 		if (err) {
54 			*err_term = term;
55 			break;
56 		}
57 	}
58 
59 	return err;
60 }
61 
perf_evlist__apply_drv_configs(struct perf_evlist * evlist,struct perf_evsel ** err_evsel,struct perf_evsel_config_term ** err_term)62 int perf_evlist__apply_drv_configs(struct perf_evlist *evlist,
63 				   struct perf_evsel **err_evsel,
64 				   struct perf_evsel_config_term **err_term)
65 {
66 	struct perf_evsel *evsel;
67 	int err = 0;
68 
69 	evlist__for_each_entry(evlist, evsel) {
70 		err = perf_evsel__apply_drv_configs(evsel, err_term);
71 		if (err) {
72 			*err_evsel = evsel;
73 			break;
74 		}
75 	}
76 
77 	return err;
78 }
79