Linux Audio

Check our new training course

Loading...
v3.5.6
  1
  2#include <linux/list.h>
 
 
 
 
 
  3#include <sys/types.h>
 
 
  4#include <sys/stat.h>
  5#include <unistd.h>
  6#include <stdio.h>
 
 
  7#include <dirent.h>
  8#include "sysfs.h"
  9#include "util.h"
 
 
 
 
 
 10#include "pmu.h"
 11#include "parse-events.h"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 12
 13int perf_pmu_parse(struct list_head *list, char *name);
 14extern FILE *perf_pmu_in;
 15
 16static LIST_HEAD(pmus);
 
 17
 18/*
 19 * Parse & process all the sysfs attributes located under
 20 * the directory specified in 'dir' parameter.
 21 */
 22static int pmu_format_parse(char *dir, struct list_head *head)
 23{
 24	struct dirent *evt_ent;
 25	DIR *format_dir;
 26	int ret = 0;
 27
 28	format_dir = opendir(dir);
 29	if (!format_dir)
 30		return -EINVAL;
 31
 32	while (!ret && (evt_ent = readdir(format_dir))) {
 33		char path[PATH_MAX];
 34		char *name = evt_ent->d_name;
 35		FILE *file;
 36
 37		if (!strcmp(name, ".") || !strcmp(name, ".."))
 38			continue;
 39
 40		snprintf(path, PATH_MAX, "%s/%s", dir, name);
 41
 42		ret = -EINVAL;
 43		file = fopen(path, "r");
 44		if (!file)
 45			break;
 46
 47		perf_pmu_in = file;
 48		ret = perf_pmu_parse(head, name);
 49		fclose(file);
 50	}
 51
 52	closedir(format_dir);
 53	return ret;
 54}
 55
 56/*
 57 * Reading/parsing the default pmu format definition, which should be
 58 * located at:
 59 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
 60 */
 61static int pmu_format(char *name, struct list_head *format)
 62{
 63	struct stat st;
 64	char path[PATH_MAX];
 65	const char *sysfs;
 66
 67	sysfs = sysfs_find_mountpoint();
 68	if (!sysfs)
 69		return -1;
 70
 71	snprintf(path, PATH_MAX,
 72		 "%s/bus/event_source/devices/%s/format", sysfs, name);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 73
 74	if (stat(path, &st) < 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 75		return -1;
 76
 77	if (pmu_format_parse(path, format))
 
 
 
 
 
 
 78		return -1;
 79
 80	return 0;
 81}
 82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 83/*
 84 * Reading/parsing the default pmu type value, which should be
 85 * located at:
 86 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
 87 */
 88static int pmu_type(char *name, __u32 *type)
 89{
 90	struct stat st;
 91	char path[PATH_MAX];
 92	const char *sysfs;
 93	FILE *file;
 94	int ret = 0;
 
 95
 96	sysfs = sysfs_find_mountpoint();
 97	if (!sysfs)
 98		return -1;
 99
100	snprintf(path, PATH_MAX,
101		 "%s/bus/event_source/devices/%s/type", sysfs, name);
102
103	if (stat(path, &st) < 0)
104		return -1;
105
106	file = fopen(path, "r");
107	if (!file)
108		return -EINVAL;
109
110	if (1 != fscanf(file, "%u", type))
111		ret = -1;
112
113	fclose(file);
114	return ret;
115}
116
117static struct perf_pmu *pmu_lookup(char *name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118{
119	struct perf_pmu *pmu;
120	LIST_HEAD(format);
 
121	__u32 type;
 
 
 
 
 
 
 
122
123	/*
124	 * The pmu data we store & need consists of the pmu
125	 * type value and format definitions. Load both right
126	 * now.
127	 */
128	if (pmu_format(name, &format))
129		return NULL;
130
 
 
 
131	if (pmu_type(name, &type))
132		return NULL;
133
 
 
 
134	pmu = zalloc(sizeof(*pmu));
135	if (!pmu)
136		return NULL;
137
138	INIT_LIST_HEAD(&pmu->format);
139	list_splice(&format, &pmu->format);
140	pmu->name = strdup(name);
141	pmu->type = type;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142	return pmu;
143}
144
145static struct perf_pmu *pmu_find(char *name)
146{
147	struct perf_pmu *pmu;
148
149	list_for_each_entry(pmu, &pmus, list)
150		if (!strcmp(pmu->name, name))
151			return pmu;
152
153	return NULL;
154}
155
156struct perf_pmu *perf_pmu__find(char *name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157{
158	struct perf_pmu *pmu;
159
160	/*
161	 * Once PMU is loaded it stays in the list,
162	 * so we keep us from multiple reading/parsing
163	 * the pmu format definitions.
164	 */
165	pmu = pmu_find(name);
166	if (pmu)
167		return pmu;
168
169	return pmu_lookup(name);
170}
171
172static struct perf_pmu__format*
173pmu_find_format(struct list_head *formats, char *name)
174{
175	struct perf_pmu__format *format;
176
177	list_for_each_entry(format, formats, list)
178		if (!strcmp(format->name, name))
179			return format;
180
181	return NULL;
182}
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184/*
185 * Returns value based on the format definition (format parameter)
186 * and unformated value (value parameter).
187 *
188 * TODO maybe optimize a little ;)
189 */
190static __u64 pmu_format_value(unsigned long *format, __u64 value)
 
191{
192	unsigned long fbit, vbit;
193	__u64 v = 0;
194
195	for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
196
197		if (!test_bit(fbit, format))
198			continue;
199
200		if (!(value & (1llu << vbit++)))
201			continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
203		v |= (1llu << fbit);
 
 
 
 
 
 
204	}
205
206	return v;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207}
208
209/*
210 * Setup one of config[12] attr members based on the
211 * user input data - temr parameter.
212 */
213static int pmu_config_term(struct list_head *formats,
 
214			   struct perf_event_attr *attr,
215			   struct parse_events__term *term)
 
 
216{
217	struct perf_pmu__format *format;
218	__u64 *vp;
 
 
 
 
 
 
 
 
219
220	/*
221	 * Support only for hardcoded and numnerial terms.
222	 * Hardcoded terms should be already in, so nothing
223	 * to be done for them.
224	 */
225	if (parse_events__is_hardcoded_term(term))
226		return 0;
227
228	if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
229		return -EINVAL;
230
231	format = pmu_find_format(formats, term->config);
232	if (!format)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233		return -EINVAL;
 
234
235	switch (format->value) {
236	case PERF_PMU_FORMAT_VALUE_CONFIG:
237		vp = &attr->config;
238		break;
239	case PERF_PMU_FORMAT_VALUE_CONFIG1:
240		vp = &attr->config1;
241		break;
242	case PERF_PMU_FORMAT_VALUE_CONFIG2:
243		vp = &attr->config2;
244		break;
245	default:
246		return -EINVAL;
247	}
248
249	/*
250	 * XXX If we ever decide to go with string values for
251	 * non-hardcoded terms, here's the place to translate
252	 * them into value.
253	 */
254	*vp |= pmu_format_value(format->bits, term->val.num);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255	return 0;
256}
257
258static int pmu_config(struct list_head *formats, struct perf_event_attr *attr,
259		      struct list_head *head_terms)
 
 
260{
261	struct parse_events__term *term;
262
263	list_for_each_entry(term, head_terms, list)
264		if (pmu_config_term(formats, attr, term))
 
265			return -EINVAL;
 
266
267	return 0;
268}
269
270/*
271 * Configures event's 'attr' parameter based on the:
272 * 1) users input - specified in terms parameter
273 * 2) pmu format definitions - specified by pmu parameter
274 */
275int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
276		     struct list_head *head_terms)
 
277{
 
 
278	attr->type = pmu->type;
279	return pmu_config(&pmu->format, attr, head_terms);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280}
281
282int perf_pmu__new_format(struct list_head *list, char *name,
283			 int config, unsigned long *bits)
284{
285	struct perf_pmu__format *format;
286
287	format = zalloc(sizeof(*format));
288	if (!format)
289		return -ENOMEM;
290
291	format->name = strdup(name);
292	format->value = config;
293	memcpy(format->bits, bits, sizeof(format->bits));
294
295	list_add_tail(&format->list, list);
296	return 0;
297}
298
299void perf_pmu__set_format(unsigned long *bits, long from, long to)
300{
301	long b;
302
303	if (!to)
304		to = from;
305
306	memset(bits, 0, BITS_TO_LONGS(PERF_PMU_FORMAT_BITS));
307	for (b = from; b <= to; b++)
308		set_bit(b, bits);
309}
310
311/* Simulated format definitions. */
312static struct test_format {
313	const char *name;
314	const char *value;
315} test_formats[] = {
316	{ "krava01", "config:0-1,62-63\n", },
317	{ "krava02", "config:10-17\n", },
318	{ "krava03", "config:5\n", },
319	{ "krava11", "config1:0,2,4,6,8,20-28\n", },
320	{ "krava12", "config1:63\n", },
321	{ "krava13", "config1:45-47\n", },
322	{ "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
323	{ "krava22", "config2:8,18,48,58\n", },
324	{ "krava23", "config2:28-29,38\n", },
325};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
327#define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format))
 
 
 
 
 
328
329/* Simulated users input. */
330static struct parse_events__term test_terms[] = {
331	{
332		.config    = (char *) "krava01",
333		.val.num   = 15,
334		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
335		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
336	},
337	{
338		.config    = (char *) "krava02",
339		.val.num   = 170,
340		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
341		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
342	},
343	{
344		.config    = (char *) "krava03",
345		.val.num   = 1,
346		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
347		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
348	},
349	{
350		.config    = (char *) "krava11",
351		.val.num   = 27,
352		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
353		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
354	},
355	{
356		.config    = (char *) "krava12",
357		.val.num   = 1,
358		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
359		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
360	},
361	{
362		.config    = (char *) "krava13",
363		.val.num   = 2,
364		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
365		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
366	},
367	{
368		.config    = (char *) "krava21",
369		.val.num   = 119,
370		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
371		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
372	},
373	{
374		.config    = (char *) "krava22",
375		.val.num   = 11,
376		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
377		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
378	},
379	{
380		.config    = (char *) "krava23",
381		.val.num   = 2,
382		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
383		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
384	},
385};
386#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term))
387
388/*
389 * Prepare format directory data, exported by kernel
390 * at /sys/bus/event_source/devices/<dev>/format.
391 */
392static char *test_format_dir_get(void)
393{
394	static char dir[PATH_MAX];
395	unsigned int i;
396
397	snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX");
398	if (!mkdtemp(dir))
399		return NULL;
 
 
400
401	for (i = 0; i < TEST_FORMATS_CNT; i++) {
402		static char name[PATH_MAX];
403		struct test_format *format = &test_formats[i];
404		FILE *file;
405
406		snprintf(name, PATH_MAX, "%s/%s", dir, format->name);
 
 
407
408		file = fopen(name, "w");
409		if (!file)
410			return NULL;
411
412		if (1 != fwrite(format->value, strlen(format->value), 1, file))
413			break;
 
 
414
415		fclose(file);
 
 
 
 
 
 
 
 
 
 
 
 
416	}
 
417
418	return dir;
 
 
419}
420
421/* Cleanup format directory. */
422static int test_format_dir_put(char *dir)
423{
424	char buf[PATH_MAX];
425	snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir);
426	if (system(buf))
427		return -1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
429	snprintf(buf, PATH_MAX, "rmdir %s\n", dir);
430	return system(buf);
 
 
 
 
 
 
 
431}
432
433static struct list_head *test_terms_list(void)
434{
435	static LIST_HEAD(terms);
436	unsigned int i;
437
438	for (i = 0; i < TERMS_CNT; i++)
439		list_add_tail(&test_terms[i].list, &terms);
 
440
441	return &terms;
 
 
 
 
442}
443
444#undef TERMS_CNT
 
 
 
 
 
445
446int perf_pmu__test(void)
 
 
 
 
 
 
 
 
 
 
447{
448	char *format = test_format_dir_get();
449	LIST_HEAD(formats);
450	struct list_head *terms = test_terms_list();
451	int ret;
452
453	if (!format)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454		return -EINVAL;
455
456	do {
457		struct perf_event_attr attr;
 
 
 
458
459		memset(&attr, 0, sizeof(attr));
 
460
461		ret = pmu_format_parse(format, &formats);
462		if (ret)
463			break;
464
465		ret = pmu_config(&formats, &attr, terms);
466		if (ret)
467			break;
468
469		ret = -EINVAL;
 
 
 
 
470
471		if (attr.config  != 0xc00000000002a823)
472			break;
473		if (attr.config1 != 0x8000400000000145)
474			break;
475		if (attr.config2 != 0x0400000020041d07)
476			break;
477
478		ret = 0;
479	} while (0);
480
481	test_format_dir_put(format);
482	return ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483}
v5.14.15
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/list.h>
   3#include <linux/compiler.h>
   4#include <linux/string.h>
   5#include <linux/zalloc.h>
   6#include <linux/ctype.h>
   7#include <subcmd/pager.h>
   8#include <sys/types.h>
   9#include <errno.h>
  10#include <fcntl.h>
  11#include <sys/stat.h>
  12#include <unistd.h>
  13#include <stdio.h>
  14#include <stdbool.h>
  15#include <stdarg.h>
  16#include <dirent.h>
  17#include <api/fs/fs.h>
  18#include <locale.h>
  19#include <regex.h>
  20#include <perf/cpumap.h>
  21#include <fnmatch.h>
  22#include "debug.h"
  23#include "evsel.h"
  24#include "pmu.h"
  25#include "parse-events.h"
  26#include "header.h"
  27#include "string2.h"
  28#include "strbuf.h"
  29#include "fncache.h"
  30#include "pmu-hybrid.h"
  31
  32struct perf_pmu perf_pmu__fake;
  33
  34struct perf_pmu_format {
  35	char *name;
  36	int value;
  37	DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
  38	struct list_head list;
  39};
  40
  41int perf_pmu_parse(struct list_head *list, char *name);
  42extern FILE *perf_pmu_in;
  43
  44static LIST_HEAD(pmus);
  45static bool hybrid_scanned;
  46
  47/*
  48 * Parse & process all the sysfs attributes located under
  49 * the directory specified in 'dir' parameter.
  50 */
  51int perf_pmu__format_parse(char *dir, struct list_head *head)
  52{
  53	struct dirent *evt_ent;
  54	DIR *format_dir;
  55	int ret = 0;
  56
  57	format_dir = opendir(dir);
  58	if (!format_dir)
  59		return -EINVAL;
  60
  61	while (!ret && (evt_ent = readdir(format_dir))) {
  62		char path[PATH_MAX];
  63		char *name = evt_ent->d_name;
  64		FILE *file;
  65
  66		if (!strcmp(name, ".") || !strcmp(name, ".."))
  67			continue;
  68
  69		snprintf(path, PATH_MAX, "%s/%s", dir, name);
  70
  71		ret = -EINVAL;
  72		file = fopen(path, "r");
  73		if (!file)
  74			break;
  75
  76		perf_pmu_in = file;
  77		ret = perf_pmu_parse(head, name);
  78		fclose(file);
  79	}
  80
  81	closedir(format_dir);
  82	return ret;
  83}
  84
  85/*
  86 * Reading/parsing the default pmu format definition, which should be
  87 * located at:
  88 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
  89 */
  90static int pmu_format(const char *name, struct list_head *format)
  91{
 
  92	char path[PATH_MAX];
  93	const char *sysfs = sysfs__mountpoint();
  94
 
  95	if (!sysfs)
  96		return -1;
  97
  98	snprintf(path, PATH_MAX,
  99		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
 100
 101	if (!file_available(path))
 102		return 0;
 103
 104	if (perf_pmu__format_parse(path, format))
 105		return -1;
 106
 107	return 0;
 108}
 109
 110int perf_pmu__convert_scale(const char *scale, char **end, double *sval)
 111{
 112	char *lc;
 113	int ret = 0;
 114
 115	/*
 116	 * save current locale
 117	 */
 118	lc = setlocale(LC_NUMERIC, NULL);
 119
 120	/*
 121	 * The lc string may be allocated in static storage,
 122	 * so get a dynamic copy to make it survive setlocale
 123	 * call below.
 124	 */
 125	lc = strdup(lc);
 126	if (!lc) {
 127		ret = -ENOMEM;
 128		goto out;
 129	}
 130
 131	/*
 132	 * force to C locale to ensure kernel
 133	 * scale string is converted correctly.
 134	 * kernel uses default C locale.
 135	 */
 136	setlocale(LC_NUMERIC, "C");
 137
 138	*sval = strtod(scale, end);
 139
 140out:
 141	/* restore locale */
 142	setlocale(LC_NUMERIC, lc);
 143	free(lc);
 144	return ret;
 145}
 146
 147static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
 148{
 149	struct stat st;
 150	ssize_t sret;
 151	char scale[128];
 152	int fd, ret = -1;
 153	char path[PATH_MAX];
 154
 155	scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
 156
 157	fd = open(path, O_RDONLY);
 158	if (fd == -1)
 159		return -1;
 160
 161	if (fstat(fd, &st) < 0)
 162		goto error;
 163
 164	sret = read(fd, scale, sizeof(scale)-1);
 165	if (sret < 0)
 166		goto error;
 167
 168	if (scale[sret - 1] == '\n')
 169		scale[sret - 1] = '\0';
 170	else
 171		scale[sret] = '\0';
 172
 173	ret = perf_pmu__convert_scale(scale, NULL, &alias->scale);
 174error:
 175	close(fd);
 176	return ret;
 177}
 178
 179static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
 180{
 181	char path[PATH_MAX];
 182	ssize_t sret;
 183	int fd;
 184
 185	scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
 186
 187	fd = open(path, O_RDONLY);
 188	if (fd == -1)
 189		return -1;
 190
 191	sret = read(fd, alias->unit, UNIT_MAX_LEN);
 192	if (sret < 0)
 193		goto error;
 194
 195	close(fd);
 196
 197	if (alias->unit[sret - 1] == '\n')
 198		alias->unit[sret - 1] = '\0';
 199	else
 200		alias->unit[sret] = '\0';
 201
 202	return 0;
 203error:
 204	close(fd);
 205	alias->unit[0] = '\0';
 206	return -1;
 207}
 208
 209static int
 210perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
 211{
 212	char path[PATH_MAX];
 213	int fd;
 214
 215	scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
 216
 217	fd = open(path, O_RDONLY);
 218	if (fd == -1)
 219		return -1;
 220
 221	close(fd);
 222
 223	alias->per_pkg = true;
 224	return 0;
 225}
 226
 227static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
 228				    char *dir, char *name)
 229{
 230	char path[PATH_MAX];
 231	int fd;
 232
 233	scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
 234
 235	fd = open(path, O_RDONLY);
 236	if (fd == -1)
 237		return -1;
 238
 239	alias->snapshot = true;
 240	close(fd);
 241	return 0;
 242}
 243
 244static void perf_pmu_assign_str(char *name, const char *field, char **old_str,
 245				char **new_str)
 246{
 247	if (!*old_str)
 248		goto set_new;
 249
 250	if (*new_str) {	/* Have new string, check with old */
 251		if (strcasecmp(*old_str, *new_str))
 252			pr_debug("alias %s differs in field '%s'\n",
 253				 name, field);
 254		zfree(old_str);
 255	} else		/* Nothing new --> keep old string */
 256		return;
 257set_new:
 258	*old_str = *new_str;
 259	*new_str = NULL;
 260}
 261
 262static void perf_pmu_update_alias(struct perf_pmu_alias *old,
 263				  struct perf_pmu_alias *newalias)
 264{
 265	perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc);
 266	perf_pmu_assign_str(old->name, "long_desc", &old->long_desc,
 267			    &newalias->long_desc);
 268	perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic);
 269	perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr,
 270			    &newalias->metric_expr);
 271	perf_pmu_assign_str(old->name, "metric_name", &old->metric_name,
 272			    &newalias->metric_name);
 273	perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str);
 274	old->scale = newalias->scale;
 275	old->per_pkg = newalias->per_pkg;
 276	old->snapshot = newalias->snapshot;
 277	memcpy(old->unit, newalias->unit, sizeof(old->unit));
 278}
 279
 280/* Delete an alias entry. */
 281void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
 282{
 283	zfree(&newalias->name);
 284	zfree(&newalias->desc);
 285	zfree(&newalias->long_desc);
 286	zfree(&newalias->topic);
 287	zfree(&newalias->str);
 288	zfree(&newalias->metric_expr);
 289	zfree(&newalias->metric_name);
 290	zfree(&newalias->pmu_name);
 291	parse_events_terms__purge(&newalias->terms);
 292	free(newalias);
 293}
 294
 295/* Merge an alias, search in alias list. If this name is already
 296 * present merge both of them to combine all information.
 297 */
 298static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
 299				 struct list_head *alist)
 300{
 301	struct perf_pmu_alias *a;
 302
 303	list_for_each_entry(a, alist, list) {
 304		if (!strcasecmp(newalias->name, a->name)) {
 305			if (newalias->pmu_name && a->pmu_name &&
 306			    !strcasecmp(newalias->pmu_name, a->pmu_name)) {
 307				continue;
 308			}
 309			perf_pmu_update_alias(a, newalias);
 310			perf_pmu_free_alias(newalias);
 311			return true;
 312		}
 313	}
 314	return false;
 315}
 316
 317static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 318				 char *desc, char *val, struct pmu_event *pe)
 319{
 320	struct parse_events_term *term;
 321	struct perf_pmu_alias *alias;
 322	int ret;
 323	int num;
 324	char newval[256];
 325	char *long_desc = NULL, *topic = NULL, *unit = NULL, *perpkg = NULL,
 326	     *metric_expr = NULL, *metric_name = NULL, *deprecated = NULL,
 327	     *pmu_name = NULL;
 328
 329	if (pe) {
 330		long_desc = (char *)pe->long_desc;
 331		topic = (char *)pe->topic;
 332		unit = (char *)pe->unit;
 333		perpkg = (char *)pe->perpkg;
 334		metric_expr = (char *)pe->metric_expr;
 335		metric_name = (char *)pe->metric_name;
 336		deprecated = (char *)pe->deprecated;
 337		pmu_name = (char *)pe->pmu;
 338	}
 339
 340	alias = malloc(sizeof(*alias));
 341	if (!alias)
 342		return -ENOMEM;
 343
 344	INIT_LIST_HEAD(&alias->terms);
 345	alias->scale = 1.0;
 346	alias->unit[0] = '\0';
 347	alias->per_pkg = false;
 348	alias->snapshot = false;
 349	alias->deprecated = false;
 350
 351	ret = parse_events_terms(&alias->terms, val);
 352	if (ret) {
 353		pr_err("Cannot parse alias %s: %d\n", val, ret);
 354		free(alias);
 355		return ret;
 356	}
 357
 358	/* Scan event and remove leading zeroes, spaces, newlines, some
 359	 * platforms have terms specified as
 360	 * event=0x0091 (read from files ../<PMU>/events/<FILE>
 361	 * and terms specified as event=0x91 (read from JSON files).
 362	 *
 363	 * Rebuild string to make alias->str member comparable.
 364	 */
 365	memset(newval, 0, sizeof(newval));
 366	ret = 0;
 367	list_for_each_entry(term, &alias->terms, list) {
 368		if (ret)
 369			ret += scnprintf(newval + ret, sizeof(newval) - ret,
 370					 ",");
 371		if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
 372			ret += scnprintf(newval + ret, sizeof(newval) - ret,
 373					 "%s=%#x", term->config, term->val.num);
 374		else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
 375			ret += scnprintf(newval + ret, sizeof(newval) - ret,
 376					 "%s=%s", term->config, term->val.str);
 377	}
 378
 379	alias->name = strdup(name);
 380	if (dir) {
 381		/*
 382		 * load unit name and scale if available
 383		 */
 384		perf_pmu__parse_unit(alias, dir, name);
 385		perf_pmu__parse_scale(alias, dir, name);
 386		perf_pmu__parse_per_pkg(alias, dir, name);
 387		perf_pmu__parse_snapshot(alias, dir, name);
 388	}
 389
 390	alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
 391	alias->metric_name = metric_name ? strdup(metric_name): NULL;
 392	alias->desc = desc ? strdup(desc) : NULL;
 393	alias->long_desc = long_desc ? strdup(long_desc) :
 394				desc ? strdup(desc) : NULL;
 395	alias->topic = topic ? strdup(topic) : NULL;
 396	if (unit) {
 397		if (perf_pmu__convert_scale(unit, &unit, &alias->scale) < 0)
 398			return -1;
 399		snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
 400	}
 401	alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
 402	alias->str = strdup(newval);
 403	alias->pmu_name = pmu_name ? strdup(pmu_name) : NULL;
 404
 405	if (deprecated)
 406		alias->deprecated = true;
 407
 408	if (!perf_pmu_merge_alias(alias, list))
 409		list_add_tail(&alias->list, list);
 410
 411	return 0;
 412}
 413
 414static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
 415{
 416	char buf[256];
 417	int ret;
 418
 419	ret = fread(buf, 1, sizeof(buf), file);
 420	if (ret == 0)
 421		return -EINVAL;
 422
 423	buf[ret] = 0;
 424
 425	/* Remove trailing newline from sysfs file */
 426	strim(buf);
 427
 428	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
 429}
 430
 431static inline bool pmu_alias_info_file(char *name)
 432{
 433	size_t len;
 434
 435	len = strlen(name);
 436	if (len > 5 && !strcmp(name + len - 5, ".unit"))
 437		return true;
 438	if (len > 6 && !strcmp(name + len - 6, ".scale"))
 439		return true;
 440	if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
 441		return true;
 442	if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
 443		return true;
 444
 445	return false;
 446}
 447
 448/*
 449 * Process all the sysfs attributes located under the directory
 450 * specified in 'dir' parameter.
 451 */
 452static int pmu_aliases_parse(char *dir, struct list_head *head)
 453{
 454	struct dirent *evt_ent;
 455	DIR *event_dir;
 456
 457	event_dir = opendir(dir);
 458	if (!event_dir)
 459		return -EINVAL;
 460
 461	while ((evt_ent = readdir(event_dir))) {
 462		char path[PATH_MAX];
 463		char *name = evt_ent->d_name;
 464		FILE *file;
 465
 466		if (!strcmp(name, ".") || !strcmp(name, ".."))
 467			continue;
 468
 469		/*
 470		 * skip info files parsed in perf_pmu__new_alias()
 471		 */
 472		if (pmu_alias_info_file(name))
 473			continue;
 474
 475		scnprintf(path, PATH_MAX, "%s/%s", dir, name);
 476
 477		file = fopen(path, "r");
 478		if (!file) {
 479			pr_debug("Cannot open %s\n", path);
 480			continue;
 481		}
 482
 483		if (perf_pmu__new_alias(head, dir, name, file) < 0)
 484			pr_debug("Cannot set up %s\n", name);
 485		fclose(file);
 486	}
 487
 488	closedir(event_dir);
 489	return 0;
 490}
 491
 492/*
 493 * Reading the pmu event aliases definition, which should be located at:
 494 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
 495 */
 496static int pmu_aliases(const char *name, struct list_head *head)
 497{
 498	char path[PATH_MAX];
 499	const char *sysfs = sysfs__mountpoint();
 500
 501	if (!sysfs)
 502		return -1;
 503
 504	snprintf(path, PATH_MAX,
 505		 "%s/bus/event_source/devices/%s/events", sysfs, name);
 506
 507	if (!file_available(path))
 508		return 0;
 509
 510	if (pmu_aliases_parse(path, head))
 511		return -1;
 512
 513	return 0;
 514}
 515
 516static int pmu_alias_terms(struct perf_pmu_alias *alias,
 517			   struct list_head *terms)
 518{
 519	struct parse_events_term *term, *cloned;
 520	LIST_HEAD(list);
 521	int ret;
 522
 523	list_for_each_entry(term, &alias->terms, list) {
 524		ret = parse_events_term__clone(&cloned, term);
 525		if (ret) {
 526			parse_events_terms__purge(&list);
 527			return ret;
 528		}
 529		/*
 530		 * Weak terms don't override command line options,
 531		 * which we don't want for implicit terms in aliases.
 532		 */
 533		cloned->weak = true;
 534		list_add_tail(&cloned->list, &list);
 535	}
 536	list_splice(&list, terms);
 537	return 0;
 538}
 539
 540/*
 541 * Reading/parsing the default pmu type value, which should be
 542 * located at:
 543 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
 544 */
 545static int pmu_type(const char *name, __u32 *type)
 546{
 
 547	char path[PATH_MAX];
 
 548	FILE *file;
 549	int ret = 0;
 550	const char *sysfs = sysfs__mountpoint();
 551
 
 552	if (!sysfs)
 553		return -1;
 554
 555	snprintf(path, PATH_MAX,
 556		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
 557
 558	if (access(path, R_OK) < 0)
 559		return -1;
 560
 561	file = fopen(path, "r");
 562	if (!file)
 563		return -EINVAL;
 564
 565	if (1 != fscanf(file, "%u", type))
 566		ret = -1;
 567
 568	fclose(file);
 569	return ret;
 570}
 571
 572/* Add all pmus in sysfs to pmu list: */
 573static void pmu_read_sysfs(void)
 574{
 575	char path[PATH_MAX];
 576	DIR *dir;
 577	struct dirent *dent;
 578	const char *sysfs = sysfs__mountpoint();
 579
 580	if (!sysfs)
 581		return;
 582
 583	snprintf(path, PATH_MAX,
 584		 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
 585
 586	dir = opendir(path);
 587	if (!dir)
 588		return;
 589
 590	while ((dent = readdir(dir))) {
 591		if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
 592			continue;
 593		/* add to static LIST_HEAD(pmus): */
 594		perf_pmu__find(dent->d_name);
 595	}
 596
 597	closedir(dir);
 598}
 599
 600static struct perf_cpu_map *__pmu_cpumask(const char *path)
 601{
 602	FILE *file;
 603	struct perf_cpu_map *cpus;
 604
 605	file = fopen(path, "r");
 606	if (!file)
 607		return NULL;
 608
 609	cpus = perf_cpu_map__read(file);
 610	fclose(file);
 611	return cpus;
 612}
 613
 614/*
 615 * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64)
 616 * may have a "cpus" file.
 617 */
 618#define SYS_TEMPLATE_ID	"./bus/event_source/devices/%s/identifier"
 619#define CPUS_TEMPLATE_UNCORE	"%s/bus/event_source/devices/%s/cpumask"
 620
 621static struct perf_cpu_map *pmu_cpumask(const char *name)
 622{
 623	char path[PATH_MAX];
 624	struct perf_cpu_map *cpus;
 625	const char *sysfs = sysfs__mountpoint();
 626	const char *templates[] = {
 627		CPUS_TEMPLATE_UNCORE,
 628		CPUS_TEMPLATE_CPU,
 629		NULL
 630	};
 631	const char **template;
 632
 633	if (!sysfs)
 634		return NULL;
 635
 636	for (template = templates; *template; template++) {
 637		snprintf(path, PATH_MAX, *template, sysfs, name);
 638		cpus = __pmu_cpumask(path);
 639		if (cpus)
 640			return cpus;
 641	}
 642
 643	return NULL;
 644}
 645
 646static bool pmu_is_uncore(const char *name)
 647{
 648	char path[PATH_MAX];
 649	const char *sysfs;
 650
 651	if (perf_pmu__hybrid_mounted(name))
 652		return false;
 653
 654	sysfs = sysfs__mountpoint();
 655	snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
 656	return file_available(path);
 657}
 658
 659static char *pmu_id(const char *name)
 660{
 661	char path[PATH_MAX], *str;
 662	size_t len;
 663
 664	snprintf(path, PATH_MAX, SYS_TEMPLATE_ID, name);
 665
 666	if (sysfs__read_str(path, &str, &len) < 0)
 667		return NULL;
 668
 669	str[len - 1] = 0; /* remove line feed */
 670
 671	return str;
 672}
 673
 674/*
 675 *  PMU CORE devices have different name other than cpu in sysfs on some
 676 *  platforms.
 677 *  Looking for possible sysfs files to identify the arm core device.
 678 */
 679static int is_arm_pmu_core(const char *name)
 680{
 681	char path[PATH_MAX];
 682	const char *sysfs = sysfs__mountpoint();
 683
 684	if (!sysfs)
 685		return 0;
 686
 687	/* Look for cpu sysfs (specific to arm) */
 688	scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
 689				sysfs, name);
 690	return file_available(path);
 691}
 692
 693static char *perf_pmu__getcpuid(struct perf_pmu *pmu)
 694{
 695	char *cpuid;
 696	static bool printed;
 697
 698	cpuid = getenv("PERF_CPUID");
 699	if (cpuid)
 700		cpuid = strdup(cpuid);
 701	if (!cpuid)
 702		cpuid = get_cpuid_str(pmu);
 703	if (!cpuid)
 704		return NULL;
 705
 706	if (!printed) {
 707		pr_debug("Using CPUID %s\n", cpuid);
 708		printed = true;
 709	}
 710	return cpuid;
 711}
 712
 713struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
 714{
 715	struct pmu_events_map *map;
 716	char *cpuid = perf_pmu__getcpuid(pmu);
 717	int i;
 718
 719	/* on some platforms which uses cpus map, cpuid can be NULL for
 720	 * PMUs other than CORE PMUs.
 721	 */
 722	if (!cpuid)
 723		return NULL;
 724
 725	i = 0;
 726	for (;;) {
 727		map = &pmu_events_map[i++];
 728		if (!map->table) {
 729			map = NULL;
 730			break;
 731		}
 732
 733		if (!strcmp_cpuid_str(map->cpuid, cpuid))
 734			break;
 735	}
 736	free(cpuid);
 737	return map;
 738}
 739
 740struct pmu_events_map *__weak pmu_events_map__find(void)
 741{
 742	return perf_pmu__find_map(NULL);
 743}
 744
 745/*
 746 * Suffix must be in form tok_{digits}, or tok{digits}, or same as pmu_name
 747 * to be valid.
 748 */
 749static bool perf_pmu__valid_suffix(const char *pmu_name, char *tok)
 750{
 751	const char *p;
 752
 753	if (strncmp(pmu_name, tok, strlen(tok)))
 754		return false;
 755
 756	p = pmu_name + strlen(tok);
 757	if (*p == 0)
 758		return true;
 759
 760	if (*p == '_')
 761		++p;
 762
 763	/* Ensure we end in a number */
 764	while (1) {
 765		if (!isdigit(*p))
 766			return false;
 767		if (*(++p) == 0)
 768			break;
 769	}
 770
 771	return true;
 772}
 773
 774bool pmu_uncore_alias_match(const char *pmu_name, const char *name)
 775{
 776	char *tmp = NULL, *tok, *str;
 777	bool res;
 778
 779	str = strdup(pmu_name);
 780	if (!str)
 781		return false;
 782
 783	/*
 784	 * uncore alias may be from different PMU with common prefix
 785	 */
 786	tok = strtok_r(str, ",", &tmp);
 787	if (strncmp(pmu_name, tok, strlen(tok))) {
 788		res = false;
 789		goto out;
 790	}
 791
 792	/*
 793	 * Match more complex aliases where the alias name is a comma-delimited
 794	 * list of tokens, orderly contained in the matching PMU name.
 795	 *
 796	 * Example: For alias "socket,pmuname" and PMU "socketX_pmunameY", we
 797	 *	    match "socket" in "socketX_pmunameY" and then "pmuname" in
 798	 *	    "pmunameY".
 799	 */
 800	while (1) {
 801		char *next_tok = strtok_r(NULL, ",", &tmp);
 802
 803		name = strstr(name, tok);
 804		if (!name ||
 805		    (!next_tok && !perf_pmu__valid_suffix(name, tok))) {
 806			res = false;
 807			goto out;
 808		}
 809		if (!next_tok)
 810			break;
 811		tok = next_tok;
 812		name += strlen(tok);
 813	}
 814
 815	res = true;
 816out:
 817	free(str);
 818	return res;
 819}
 820
 821/*
 822 * From the pmu_events_map, find the table of PMU events that corresponds
 823 * to the current running CPU. Then, add all PMU events from that table
 824 * as aliases.
 825 */
 826void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
 827			     struct pmu_events_map *map)
 828{
 829	int i;
 830	const char *name = pmu->name;
 831	/*
 832	 * Found a matching PMU events table. Create aliases
 833	 */
 834	i = 0;
 835	while (1) {
 836		const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu";
 837		struct pmu_event *pe = &map->table[i++];
 838		const char *pname = pe->pmu ? pe->pmu : cpu_name;
 839
 840		if (!pe->name) {
 841			if (pe->metric_group || pe->metric_name)
 842				continue;
 843			break;
 844		}
 845
 846		if (pmu_is_uncore(name) &&
 847		    pmu_uncore_alias_match(pname, name))
 848			goto new_alias;
 849
 850		if (strcmp(pname, name))
 851			continue;
 852
 853new_alias:
 854		/* need type casts to override 'const' */
 855		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
 856				(char *)pe->desc, (char *)pe->event,
 857				pe);
 858	}
 859}
 860
 861static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
 862{
 863	struct pmu_events_map *map;
 864
 865	map = perf_pmu__find_map(pmu);
 866	if (!map)
 867		return;
 868
 869	pmu_add_cpu_aliases_map(head, pmu, map);
 870}
 871
 872void pmu_for_each_sys_event(pmu_sys_event_iter_fn fn, void *data)
 873{
 874	int i = 0;
 875
 876	while (1) {
 877		struct pmu_sys_events *event_table;
 878		int j = 0;
 879
 880		event_table = &pmu_sys_event_tables[i++];
 881
 882		if (!event_table->table)
 883			break;
 884
 885		while (1) {
 886			struct pmu_event *pe = &event_table->table[j++];
 887			int ret;
 888
 889			if (!pe->name && !pe->metric_group && !pe->metric_name)
 890				break;
 891
 892			ret = fn(pe, data);
 893			if (ret)
 894				break;
 895		}
 896	}
 897}
 898
 899struct pmu_sys_event_iter_data {
 900	struct list_head *head;
 901	struct perf_pmu *pmu;
 902};
 903
 904static int pmu_add_sys_aliases_iter_fn(struct pmu_event *pe, void *data)
 905{
 906	struct pmu_sys_event_iter_data *idata = data;
 907	struct perf_pmu *pmu = idata->pmu;
 908
 909	if (!pe->name) {
 910		if (pe->metric_group || pe->metric_name)
 911			return 0;
 912		return -EINVAL;
 913	}
 914
 915	if (!pe->compat || !pe->pmu)
 916		return 0;
 917
 918	if (!strcmp(pmu->id, pe->compat) &&
 919	    pmu_uncore_alias_match(pe->pmu, pmu->name)) {
 920		__perf_pmu__new_alias(idata->head, NULL,
 921				      (char *)pe->name,
 922				      (char *)pe->desc,
 923				      (char *)pe->event,
 924				      pe);
 925	}
 926
 927	return 0;
 928}
 929
 930static void pmu_add_sys_aliases(struct list_head *head, struct perf_pmu *pmu)
 931{
 932	struct pmu_sys_event_iter_data idata = {
 933		.head = head,
 934		.pmu = pmu,
 935	};
 936
 937	if (!pmu->id)
 938		return;
 939
 940	pmu_for_each_sys_event(pmu_add_sys_aliases_iter_fn, &idata);
 941}
 942
 943struct perf_event_attr * __weak
 944perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
 945{
 946	return NULL;
 947}
 948
 949static int pmu_max_precise(const char *name)
 950{
 951	char path[PATH_MAX];
 952	int max_precise = -1;
 953
 954	scnprintf(path, PATH_MAX,
 955		 "bus/event_source/devices/%s/caps/max_precise",
 956		 name);
 957
 958	sysfs__read_int(path, &max_precise);
 959	return max_precise;
 960}
 961
 962static struct perf_pmu *pmu_lookup(const char *name)
 963{
 964	struct perf_pmu *pmu;
 965	LIST_HEAD(format);
 966	LIST_HEAD(aliases);
 967	__u32 type;
 968	bool is_hybrid = perf_pmu__hybrid_mounted(name);
 969
 970	/*
 971	 * Check pmu name for hybrid and the pmu may be invalid in sysfs
 972	 */
 973	if (!strncmp(name, "cpu_", 4) && !is_hybrid)
 974		return NULL;
 975
 976	/*
 977	 * The pmu data we store & need consists of the pmu
 978	 * type value and format definitions. Load both right
 979	 * now.
 980	 */
 981	if (pmu_format(name, &format))
 982		return NULL;
 983
 984	/*
 985	 * Check the type first to avoid unnecessary work.
 986	 */
 987	if (pmu_type(name, &type))
 988		return NULL;
 989
 990	if (pmu_aliases(name, &aliases))
 991		return NULL;
 992
 993	pmu = zalloc(sizeof(*pmu));
 994	if (!pmu)
 995		return NULL;
 996
 997	pmu->cpus = pmu_cpumask(name);
 
 998	pmu->name = strdup(name);
 999	pmu->type = type;
1000	pmu->is_uncore = pmu_is_uncore(name);
1001	if (pmu->is_uncore)
1002		pmu->id = pmu_id(name);
1003	pmu->is_hybrid = is_hybrid;
1004	pmu->max_precise = pmu_max_precise(name);
1005	pmu_add_cpu_aliases(&aliases, pmu);
1006	pmu_add_sys_aliases(&aliases, pmu);
1007
1008	INIT_LIST_HEAD(&pmu->format);
1009	INIT_LIST_HEAD(&pmu->aliases);
1010	INIT_LIST_HEAD(&pmu->caps);
1011	list_splice(&format, &pmu->format);
1012	list_splice(&aliases, &pmu->aliases);
1013	list_add_tail(&pmu->list, &pmus);
1014
1015	if (pmu->is_hybrid)
1016		list_add_tail(&pmu->hybrid_list, &perf_pmu__hybrid_pmus);
1017
1018	pmu->default_config = perf_pmu__get_default_config(pmu);
1019
1020	return pmu;
1021}
1022
1023static struct perf_pmu *pmu_find(const char *name)
1024{
1025	struct perf_pmu *pmu;
1026
1027	list_for_each_entry(pmu, &pmus, list)
1028		if (!strcmp(pmu->name, name))
1029			return pmu;
1030
1031	return NULL;
1032}
1033
1034struct perf_pmu *perf_pmu__find_by_type(unsigned int type)
1035{
1036	struct perf_pmu *pmu;
1037
1038	list_for_each_entry(pmu, &pmus, list)
1039		if (pmu->type == type)
1040			return pmu;
1041
1042	return NULL;
1043}
1044
1045struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
1046{
1047	/*
1048	 * pmu iterator: If pmu is NULL, we start at the begin,
1049	 * otherwise return the next pmu. Returns NULL on end.
1050	 */
1051	if (!pmu) {
1052		pmu_read_sysfs();
1053		pmu = list_prepare_entry(pmu, &pmus, list);
1054	}
1055	list_for_each_entry_continue(pmu, &pmus, list)
1056		return pmu;
1057	return NULL;
1058}
1059
1060struct perf_pmu *evsel__find_pmu(struct evsel *evsel)
1061{
1062	struct perf_pmu *pmu = NULL;
1063
1064	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1065		if (pmu->type == evsel->core.attr.type)
1066			break;
1067	}
1068
1069	return pmu;
1070}
1071
1072bool evsel__is_aux_event(struct evsel *evsel)
1073{
1074	struct perf_pmu *pmu = evsel__find_pmu(evsel);
1075
1076	return pmu && pmu->auxtrace;
1077}
1078
1079struct perf_pmu *perf_pmu__find(const char *name)
1080{
1081	struct perf_pmu *pmu;
1082
1083	/*
1084	 * Once PMU is loaded it stays in the list,
1085	 * so we keep us from multiple reading/parsing
1086	 * the pmu format definitions.
1087	 */
1088	pmu = pmu_find(name);
1089	if (pmu)
1090		return pmu;
1091
1092	return pmu_lookup(name);
1093}
1094
1095static struct perf_pmu_format *
1096pmu_find_format(struct list_head *formats, const char *name)
1097{
1098	struct perf_pmu_format *format;
1099
1100	list_for_each_entry(format, formats, list)
1101		if (!strcmp(format->name, name))
1102			return format;
1103
1104	return NULL;
1105}
1106
1107__u64 perf_pmu__format_bits(struct list_head *formats, const char *name)
1108{
1109	struct perf_pmu_format *format = pmu_find_format(formats, name);
1110	__u64 bits = 0;
1111	int fbit;
1112
1113	if (!format)
1114		return 0;
1115
1116	for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)
1117		bits |= 1ULL << fbit;
1118
1119	return bits;
1120}
1121
1122int perf_pmu__format_type(struct list_head *formats, const char *name)
1123{
1124	struct perf_pmu_format *format = pmu_find_format(formats, name);
1125
1126	if (!format)
1127		return -1;
1128
1129	return format->value;
1130}
1131
1132/*
1133 * Sets value based on the format definition (format parameter)
1134 * and unformatted value (value parameter).
 
 
1135 */
1136static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
1137			     bool zero)
1138{
1139	unsigned long fbit, vbit;
 
1140
1141	for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
1142
1143		if (!test_bit(fbit, format))
1144			continue;
1145
1146		if (value & (1llu << vbit++))
1147			*v |= (1llu << fbit);
1148		else if (zero)
1149			*v &= ~(1llu << fbit);
1150	}
1151}
1152
1153static __u64 pmu_format_max_value(const unsigned long *format)
1154{
1155	int w;
1156
1157	w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
1158	if (!w)
1159		return 0;
1160	if (w < 64)
1161		return (1ULL << w) - 1;
1162	return -1;
1163}
1164
1165/*
1166 * Term is a string term, and might be a param-term. Try to look up it's value
1167 * in the remaining terms.
1168 * - We have a term like "base-or-format-term=param-term",
1169 * - We need to find the value supplied for "param-term" (with param-term named
1170 *   in a config string) later on in the term list.
1171 */
1172static int pmu_resolve_param_term(struct parse_events_term *term,
1173				  struct list_head *head_terms,
1174				  __u64 *value)
1175{
1176	struct parse_events_term *t;
1177
1178	list_for_each_entry(t, head_terms, list) {
1179		if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM &&
1180		    t->config && !strcmp(t->config, term->config)) {
1181			t->used = true;
1182			*value = t->val.num;
1183			return 0;
1184		}
1185	}
1186
1187	if (verbose > 0)
1188		printf("Required parameter '%s' not specified\n", term->config);
1189
1190	return -1;
1191}
1192
1193static char *pmu_formats_string(struct list_head *formats)
1194{
1195	struct perf_pmu_format *format;
1196	char *str = NULL;
1197	struct strbuf buf = STRBUF_INIT;
1198	unsigned i = 0;
1199
1200	if (!formats)
1201		return NULL;
1202
1203	/* sysfs exported terms */
1204	list_for_each_entry(format, formats, list)
1205		if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
1206			goto error;
1207
1208	str = strbuf_detach(&buf, NULL);
1209error:
1210	strbuf_release(&buf);
1211
1212	return str;
1213}
1214
1215/*
1216 * Setup one of config[12] attr members based on the
1217 * user input data - term parameter.
1218 */
1219static int pmu_config_term(const char *pmu_name,
1220			   struct list_head *formats,
1221			   struct perf_event_attr *attr,
1222			   struct parse_events_term *term,
1223			   struct list_head *head_terms,
1224			   bool zero, struct parse_events_error *err)
1225{
1226	struct perf_pmu_format *format;
1227	__u64 *vp;
1228	__u64 val, max_val;
1229
1230	/*
1231	 * If this is a parameter we've already used for parameterized-eval,
1232	 * skip it in normal eval.
1233	 */
1234	if (term->used)
1235		return 0;
1236
1237	/*
 
1238	 * Hardcoded terms should be already in, so nothing
1239	 * to be done for them.
1240	 */
1241	if (parse_events__is_hardcoded_term(term))
1242		return 0;
1243
 
 
 
1244	format = pmu_find_format(formats, term->config);
1245	if (!format) {
1246		char *pmu_term = pmu_formats_string(formats);
1247		char *unknown_term;
1248		char *help_msg;
1249
1250		if (asprintf(&unknown_term,
1251				"unknown term '%s' for pmu '%s'",
1252				term->config, pmu_name) < 0)
1253			unknown_term = NULL;
1254		help_msg = parse_events_formats_error_string(pmu_term);
1255		if (err) {
1256			parse_events__handle_error(err, term->err_term,
1257						   unknown_term,
1258						   help_msg);
1259		} else {
1260			pr_debug("%s (%s)\n", unknown_term, help_msg);
1261			free(unknown_term);
1262		}
1263		free(pmu_term);
1264		return -EINVAL;
1265	}
1266
1267	switch (format->value) {
1268	case PERF_PMU_FORMAT_VALUE_CONFIG:
1269		vp = &attr->config;
1270		break;
1271	case PERF_PMU_FORMAT_VALUE_CONFIG1:
1272		vp = &attr->config1;
1273		break;
1274	case PERF_PMU_FORMAT_VALUE_CONFIG2:
1275		vp = &attr->config2;
1276		break;
1277	default:
1278		return -EINVAL;
1279	}
1280
1281	/*
1282	 * Either directly use a numeric term, or try to translate string terms
1283	 * using event parameters.
 
1284	 */
1285	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
1286		if (term->no_value &&
1287		    bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
1288			if (err) {
1289				parse_events__handle_error(err, term->err_val,
1290					   strdup("no value assigned for term"),
1291					   NULL);
1292			}
1293			return -EINVAL;
1294		}
1295
1296		val = term->val.num;
1297	} else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
1298		if (strcmp(term->val.str, "?")) {
1299			if (verbose > 0) {
1300				pr_info("Invalid sysfs entry %s=%s\n",
1301						term->config, term->val.str);
1302			}
1303			if (err) {
1304				parse_events__handle_error(err, term->err_val,
1305					strdup("expected numeric value"),
1306					NULL);
1307			}
1308			return -EINVAL;
1309		}
1310
1311		if (pmu_resolve_param_term(term, head_terms, &val))
1312			return -EINVAL;
1313	} else
1314		return -EINVAL;
1315
1316	max_val = pmu_format_max_value(format->bits);
1317	if (val > max_val) {
1318		if (err) {
1319			char *err_str;
1320
1321			parse_events__handle_error(err, term->err_val,
1322				asprintf(&err_str,
1323				    "value too big for format, maximum is %llu",
1324				    (unsigned long long)max_val) < 0
1325				    ? strdup("value too big for format")
1326				    : err_str,
1327				    NULL);
1328			return -EINVAL;
1329		}
1330		/*
1331		 * Assume we don't care if !err, in which case the value will be
1332		 * silently truncated.
1333		 */
1334	}
1335
1336	pmu_format_value(format->bits, val, vp, zero);
1337	return 0;
1338}
1339
1340int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats,
1341			   struct perf_event_attr *attr,
1342			   struct list_head *head_terms,
1343			   bool zero, struct parse_events_error *err)
1344{
1345	struct parse_events_term *term;
1346
1347	list_for_each_entry(term, head_terms, list) {
1348		if (pmu_config_term(pmu_name, formats, attr, term, head_terms,
1349				    zero, err))
1350			return -EINVAL;
1351	}
1352
1353	return 0;
1354}
1355
1356/*
1357 * Configures event's 'attr' parameter based on the:
1358 * 1) users input - specified in terms parameter
1359 * 2) pmu format definitions - specified by pmu parameter
1360 */
1361int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
1362		     struct list_head *head_terms,
1363		     struct parse_events_error *err)
1364{
1365	bool zero = !!pmu->default_config;
1366
1367	attr->type = pmu->type;
1368	return perf_pmu__config_terms(pmu->name, &pmu->format, attr,
1369				      head_terms, zero, err);
1370}
1371
1372static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
1373					     struct parse_events_term *term)
1374{
1375	struct perf_pmu_alias *alias;
1376	char *name;
1377
1378	if (parse_events__is_hardcoded_term(term))
1379		return NULL;
1380
1381	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
1382		if (term->val.num != 1)
1383			return NULL;
1384		if (pmu_find_format(&pmu->format, term->config))
1385			return NULL;
1386		name = term->config;
1387	} else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
1388		if (strcasecmp(term->config, "event"))
1389			return NULL;
1390		name = term->val.str;
1391	} else {
1392		return NULL;
1393	}
1394
1395	list_for_each_entry(alias, &pmu->aliases, list) {
1396		if (!strcasecmp(alias->name, name))
1397			return alias;
1398	}
1399	return NULL;
1400}
1401
1402
1403static int check_info_data(struct perf_pmu_alias *alias,
1404			   struct perf_pmu_info *info)
1405{
1406	/*
1407	 * Only one term in event definition can
1408	 * define unit, scale and snapshot, fail
1409	 * if there's more than one.
1410	 */
1411	if ((info->unit && alias->unit[0]) ||
1412	    (info->scale && alias->scale) ||
1413	    (info->snapshot && alias->snapshot))
1414		return -EINVAL;
1415
1416	if (alias->unit[0])
1417		info->unit = alias->unit;
1418
1419	if (alias->scale)
1420		info->scale = alias->scale;
1421
1422	if (alias->snapshot)
1423		info->snapshot = alias->snapshot;
1424
1425	return 0;
1426}
1427
1428/*
1429 * Find alias in the terms list and replace it with the terms
1430 * defined for the alias
1431 */
1432int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
1433			  struct perf_pmu_info *info)
1434{
1435	struct parse_events_term *term, *h;
1436	struct perf_pmu_alias *alias;
1437	int ret;
1438
1439	info->per_pkg = false;
1440
1441	/*
1442	 * Mark unit and scale as not set
1443	 * (different from default values, see below)
1444	 */
1445	info->unit     = NULL;
1446	info->scale    = 0.0;
1447	info->snapshot = false;
1448	info->metric_expr = NULL;
1449	info->metric_name = NULL;
1450
1451	list_for_each_entry_safe(term, h, head_terms, list) {
1452		alias = pmu_find_alias(pmu, term);
1453		if (!alias)
1454			continue;
1455		ret = pmu_alias_terms(alias, &term->list);
1456		if (ret)
1457			return ret;
1458
1459		ret = check_info_data(alias, info);
1460		if (ret)
1461			return ret;
1462
1463		if (alias->per_pkg)
1464			info->per_pkg = true;
1465		info->metric_expr = alias->metric_expr;
1466		info->metric_name = alias->metric_name;
1467
1468		list_del_init(&term->list);
1469		parse_events_term__delete(term);
1470	}
1471
1472	/*
1473	 * if no unit or scale found in aliases, then
1474	 * set defaults as for evsel
1475	 * unit cannot left to NULL
1476	 */
1477	if (info->unit == NULL)
1478		info->unit   = "";
1479
1480	if (info->scale == 0.0)
1481		info->scale  = 1.0;
1482
1483	return 0;
1484}
1485
1486int perf_pmu__new_format(struct list_head *list, char *name,
1487			 int config, unsigned long *bits)
1488{
1489	struct perf_pmu_format *format;
1490
1491	format = zalloc(sizeof(*format));
1492	if (!format)
1493		return -ENOMEM;
1494
1495	format->name = strdup(name);
1496	format->value = config;
1497	memcpy(format->bits, bits, sizeof(format->bits));
1498
1499	list_add_tail(&format->list, list);
1500	return 0;
1501}
1502
1503void perf_pmu__set_format(unsigned long *bits, long from, long to)
1504{
1505	long b;
1506
1507	if (!to)
1508		to = from;
1509
1510	memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
1511	for (b = from; b <= to; b++)
1512		set_bit(b, bits);
1513}
1514
1515void perf_pmu__del_formats(struct list_head *formats)
1516{
1517	struct perf_pmu_format *fmt, *tmp;
1518
1519	list_for_each_entry_safe(fmt, tmp, formats, list) {
1520		list_del(&fmt->list);
1521		free(fmt->name);
1522		free(fmt);
1523	}
1524}
1525
1526static int sub_non_neg(int a, int b)
1527{
1528	if (b > a)
1529		return 0;
1530	return a - b;
1531}
1532
1533static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
1534			  struct perf_pmu_alias *alias)
1535{
1536	struct parse_events_term *term;
1537	int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
1538
1539	list_for_each_entry(term, &alias->terms, list) {
1540		if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
1541			used += snprintf(buf + used, sub_non_neg(len, used),
1542					",%s=%s", term->config,
1543					term->val.str);
1544	}
1545
1546	if (sub_non_neg(len, used) > 0) {
1547		buf[used] = '/';
1548		used++;
1549	}
1550	if (sub_non_neg(len, used) > 0) {
1551		buf[used] = '\0';
1552		used++;
1553	} else
1554		buf[len - 1] = '\0';
1555
1556	return buf;
1557}
1558
1559static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
1560			     struct perf_pmu_alias *alias)
1561{
1562	snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
1563	return buf;
1564}
1565
1566struct sevent {
1567	char *name;
1568	char *desc;
1569	char *topic;
1570	char *str;
1571	char *pmu;
1572	char *metric_expr;
1573	char *metric_name;
1574	int is_cpu;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1575};
 
1576
1577static int cmp_sevent(const void *a, const void *b)
 
 
 
 
1578{
1579	const struct sevent *as = a;
1580	const struct sevent *bs = b;
1581
1582	/* Put extra events last */
1583	if (!!as->desc != !!bs->desc)
1584		return !!as->desc - !!bs->desc;
1585	if (as->topic && bs->topic) {
1586		int n = strcmp(as->topic, bs->topic);
1587
1588		if (n)
1589			return n;
1590	}
 
1591
1592	/* Order CPU core events to be first */
1593	if (as->is_cpu != bs->is_cpu)
1594		return bs->is_cpu - as->is_cpu;
1595
1596	return strcmp(as->name, bs->name);
1597}
 
1598
1599static void wordwrap(char *s, int start, int max, int corr)
1600{
1601	int column = start;
1602	int n;
1603
1604	while (*s) {
1605		int wlen = strcspn(s, " \t");
1606
1607		if (column + wlen >= max && column > start) {
1608			printf("\n%*s", start, "");
1609			column = start + corr;
1610		}
1611		n = printf("%s%.*s", column > start ? " " : "", wlen, s);
1612		if (n <= 0)
1613			break;
1614		s += wlen;
1615		column += n;
1616		s = skip_spaces(s);
1617	}
1618}
1619
1620bool is_pmu_core(const char *name)
1621{
1622	return !strcmp(name, "cpu") || is_arm_pmu_core(name);
1623}
1624
1625void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1626			bool long_desc, bool details_flag, bool deprecated)
1627{
1628	struct perf_pmu *pmu;
1629	struct perf_pmu_alias *alias;
1630	char buf[1024];
1631	int printed = 0;
1632	int len, j;
1633	struct sevent *aliases;
1634	int numdesc = 0;
1635	int columns = pager_get_columns();
1636	char *topic = NULL;
1637
1638	pmu = NULL;
1639	len = 0;
1640	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1641		list_for_each_entry(alias, &pmu->aliases, list)
1642			len++;
1643		if (pmu->selectable)
1644			len++;
1645	}
1646	aliases = zalloc(sizeof(struct sevent) * len);
1647	if (!aliases)
1648		goto out_enomem;
1649	pmu = NULL;
1650	j = 0;
1651	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1652		list_for_each_entry(alias, &pmu->aliases, list) {
1653			char *name = alias->desc ? alias->name :
1654				format_alias(buf, sizeof(buf), pmu, alias);
1655			bool is_cpu = is_pmu_core(pmu->name);
1656
1657			if (alias->deprecated && !deprecated)
1658				continue;
1659
1660			if (event_glob != NULL &&
1661			    !(strglobmatch_nocase(name, event_glob) ||
1662			      (!is_cpu && strglobmatch_nocase(alias->name,
1663						       event_glob)) ||
1664			      (alias->topic &&
1665			       strglobmatch_nocase(alias->topic, event_glob))))
1666				continue;
1667
1668			if (is_cpu && !name_only && !alias->desc)
1669				name = format_alias_or(buf, sizeof(buf), pmu, alias);
1670
1671			aliases[j].name = name;
1672			if (is_cpu && !name_only && !alias->desc)
1673				aliases[j].name = format_alias_or(buf,
1674								  sizeof(buf),
1675								  pmu, alias);
1676			aliases[j].name = strdup(aliases[j].name);
1677			if (!aliases[j].name)
1678				goto out_enomem;
1679
1680			aliases[j].desc = long_desc ? alias->long_desc :
1681						alias->desc;
1682			aliases[j].topic = alias->topic;
1683			aliases[j].str = alias->str;
1684			aliases[j].pmu = pmu->name;
1685			aliases[j].metric_expr = alias->metric_expr;
1686			aliases[j].metric_name = alias->metric_name;
1687			aliases[j].is_cpu = is_cpu;
1688			j++;
1689		}
1690		if (pmu->selectable &&
1691		    (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
1692			char *s;
1693			if (asprintf(&s, "%s//", pmu->name) < 0)
1694				goto out_enomem;
1695			aliases[j].name = s;
1696			j++;
1697		}
1698	}
1699	len = j;
1700	qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
1701	for (j = 0; j < len; j++) {
1702		/* Skip duplicates */
1703		if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
1704			continue;
1705		if (name_only) {
1706			printf("%s ", aliases[j].name);
1707			continue;
1708		}
1709		if (aliases[j].desc && !quiet_flag) {
1710			if (numdesc++ == 0)
1711				printf("\n");
1712			if (aliases[j].topic && (!topic ||
1713					strcmp(topic, aliases[j].topic))) {
1714				printf("%s%s:\n", topic ? "\n" : "",
1715						aliases[j].topic);
1716				topic = aliases[j].topic;
1717			}
1718			printf("  %-50s\n", aliases[j].name);
1719			printf("%*s", 8, "[");
1720			wordwrap(aliases[j].desc, 8, columns, 0);
1721			printf("]\n");
1722			if (details_flag) {
1723				printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
1724				if (aliases[j].metric_name)
1725					printf(" MetricName: %s", aliases[j].metric_name);
1726				if (aliases[j].metric_expr)
1727					printf(" MetricExpr: %s", aliases[j].metric_expr);
1728				putchar('\n');
1729			}
1730		} else
1731			printf("  %-50s [Kernel PMU event]\n", aliases[j].name);
1732		printed++;
1733	}
1734	if (printed && pager_in_use())
1735		printf("\n");
1736out_free:
1737	for (j = 0; j < len; j++)
1738		zfree(&aliases[j].name);
1739	zfree(&aliases);
1740	return;
1741
1742out_enomem:
1743	printf("FATAL: not enough memory to print PMU events\n");
1744	if (aliases)
1745		goto out_free;
1746}
1747
1748bool pmu_have_event(const char *pname, const char *name)
1749{
1750	struct perf_pmu *pmu;
1751	struct perf_pmu_alias *alias;
1752
1753	pmu = NULL;
1754	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
1755		if (strcmp(pname, pmu->name))
1756			continue;
1757		list_for_each_entry(alias, &pmu->aliases, list)
1758			if (!strcmp(alias->name, name))
1759				return true;
1760	}
1761	return false;
1762}
1763
1764static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
1765{
1766	char path[PATH_MAX];
1767	const char *sysfs;
1768
1769	sysfs = sysfs__mountpoint();
1770	if (!sysfs)
1771		return NULL;
1772
1773	snprintf(path, PATH_MAX,
1774		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
1775	if (!file_available(path))
1776		return NULL;
1777	return fopen(path, "r");
1778}
1779
1780int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
1781			...)
1782{
1783	va_list args;
1784	FILE *file;
1785	int ret = EOF;
1786
1787	va_start(args, fmt);
1788	file = perf_pmu__open_file(pmu, name);
1789	if (file) {
1790		ret = vfscanf(file, fmt, args);
1791		fclose(file);
1792	}
1793	va_end(args);
1794	return ret;
1795}
1796
1797static int perf_pmu__new_caps(struct list_head *list, char *name, char *value)
1798{
1799	struct perf_pmu_caps *caps = zalloc(sizeof(*caps));
 
 
 
1800
1801	if (!caps)
1802		return -ENOMEM;
1803
1804	caps->name = strdup(name);
1805	if (!caps->name)
1806		goto free_caps;
1807	caps->value = strndup(value, strlen(value) - 1);
1808	if (!caps->value)
1809		goto free_name;
1810	list_add_tail(&caps->list, list);
1811	return 0;
1812
1813free_name:
1814	zfree(caps->name);
1815free_caps:
1816	free(caps);
1817
1818	return -ENOMEM;
1819}
1820
1821/*
1822 * Reading/parsing the given pmu capabilities, which should be located at:
1823 * /sys/bus/event_source/devices/<dev>/caps as sysfs group attributes.
1824 * Return the number of capabilities
1825 */
1826int perf_pmu__caps_parse(struct perf_pmu *pmu)
1827{
1828	struct stat st;
1829	char caps_path[PATH_MAX];
1830	const char *sysfs = sysfs__mountpoint();
1831	DIR *caps_dir;
1832	struct dirent *evt_ent;
1833	int nr_caps = 0;
1834
1835	if (!sysfs)
1836		return -1;
1837
1838	snprintf(caps_path, PATH_MAX,
1839		 "%s" EVENT_SOURCE_DEVICE_PATH "%s/caps", sysfs, pmu->name);
1840
1841	if (stat(caps_path, &st) < 0)
1842		return 0;	/* no error if caps does not exist */
1843
1844	caps_dir = opendir(caps_path);
1845	if (!caps_dir)
1846		return -EINVAL;
1847
1848	while ((evt_ent = readdir(caps_dir)) != NULL) {
1849		char path[PATH_MAX + NAME_MAX + 1];
1850		char *name = evt_ent->d_name;
1851		char value[128];
1852		FILE *file;
1853
1854		if (!strcmp(name, ".") || !strcmp(name, ".."))
1855			continue;
1856
1857		snprintf(path, sizeof(path), "%s/%s", caps_path, name);
 
 
1858
1859		file = fopen(path, "r");
1860		if (!file)
1861			continue;
1862
1863		if (!fgets(value, sizeof(value), file) ||
1864		    (perf_pmu__new_caps(&pmu->caps, name, value) < 0)) {
1865			fclose(file);
1866			continue;
1867		}
1868
1869		nr_caps++;
1870		fclose(file);
1871	}
 
 
 
1872
1873	closedir(caps_dir);
 
1874
1875	return nr_caps;
1876}
1877
1878void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
1879				   char *name)
1880{
1881	struct perf_pmu_format *format;
1882	__u64 masks = 0, bits;
1883	char buf[100];
1884	unsigned int i;
1885
1886	list_for_each_entry(format, &pmu->format, list)	{
1887		if (format->value != PERF_PMU_FORMAT_VALUE_CONFIG)
1888			continue;
1889
1890		for_each_set_bit(i, format->bits, PERF_PMU_FORMAT_BITS)
1891			masks |= 1ULL << i;
1892	}
1893
1894	/*
1895	 * Kernel doesn't export any valid format bits.
1896	 */
1897	if (masks == 0)
1898		return;
1899
1900	bits = config & ~masks;
1901	if (bits == 0)
1902		return;
1903
1904	bitmap_scnprintf((unsigned long *)&bits, sizeof(bits) * 8, buf, sizeof(buf));
1905
1906	pr_warning("WARNING: event '%s' not valid (bits %s of config "
1907		   "'%llx' not supported by kernel)!\n",
1908		   name ?: "N/A", buf, config);
1909}
1910
1911bool perf_pmu__has_hybrid(void)
1912{
1913	if (!hybrid_scanned) {
1914		hybrid_scanned = true;
1915		perf_pmu__scan(NULL);
1916	}
1917
1918	return !list_empty(&perf_pmu__hybrid_pmus);
1919}
1920
1921int perf_pmu__match(char *pattern, char *name, char *tok)
1922{
1923	if (fnmatch(pattern, name, 0))
1924		return -1;
1925
1926	if (tok && !perf_pmu__valid_suffix(name, tok))
1927		return -1;
1928
1929	return 0;
1930}