Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) #include <linux/hw_breakpoint.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) #include <dirent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <sys/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <sys/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include "term.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include "build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <subcmd/pager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <subcmd/exec-cmd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "strlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "header.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include "bpf-loader.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <api/fs/tracing_path.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <perf/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include "parse-events-bison.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define YY_EXTRA_TYPE void*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include "parse-events-flex.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include "pmu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include "thread_map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include "probe-file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "asm/bug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include "util/parse-branch-options.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include "metricgroup.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include "util/evsel_config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include "util/event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include "util/pfm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include "perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define MAX_NAME_LEN 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #ifdef PARSER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) extern int parse_events_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) int parse_events_parse(void *parse_state, void *scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) static int get_config_terms(struct list_head *head_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 			    struct list_head *head_terms __maybe_unused);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) static struct perf_pmu_event_symbol *perf_pmu_events_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  * The variable indicates the number of supported pmu event symbols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * 0 means not initialized and ready to init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * -1 means failed to init, don't try anymore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * >0 is the number of supported pmu event symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) static int perf_pmu_events_list_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	[PERF_COUNT_HW_CPU_CYCLES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 		.symbol = "cpu-cycles",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 		.alias  = "cycles",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	[PERF_COUNT_HW_INSTRUCTIONS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 		.symbol = "instructions",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	[PERF_COUNT_HW_CACHE_REFERENCES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 		.symbol = "cache-references",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	[PERF_COUNT_HW_CACHE_MISSES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		.symbol = "cache-misses",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		.symbol = "branch-instructions",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 		.alias  = "branches",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	[PERF_COUNT_HW_BRANCH_MISSES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		.symbol = "branch-misses",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	[PERF_COUNT_HW_BUS_CYCLES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		.symbol = "bus-cycles",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		.symbol = "stalled-cycles-frontend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		.alias  = "idle-cycles-frontend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		.symbol = "stalled-cycles-backend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		.alias  = "idle-cycles-backend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	[PERF_COUNT_HW_REF_CPU_CYCLES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		.symbol = "ref-cycles",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	[PERF_COUNT_SW_CPU_CLOCK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		.symbol = "cpu-clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	[PERF_COUNT_SW_TASK_CLOCK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		.symbol = "task-clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	[PERF_COUNT_SW_PAGE_FAULTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		.symbol = "page-faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		.alias  = "faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	[PERF_COUNT_SW_CONTEXT_SWITCHES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		.symbol = "context-switches",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		.alias  = "cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	[PERF_COUNT_SW_CPU_MIGRATIONS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		.symbol = "cpu-migrations",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		.alias  = "migrations",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	[PERF_COUNT_SW_PAGE_FAULTS_MIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		.symbol = "minor-faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	[PERF_COUNT_SW_PAGE_FAULTS_MAJ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		.symbol = "major-faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	[PERF_COUNT_SW_ALIGNMENT_FAULTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		.symbol = "alignment-faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	[PERF_COUNT_SW_EMULATION_FAULTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		.symbol = "emulation-faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	[PERF_COUNT_SW_DUMMY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		.symbol = "dummy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	[PERF_COUNT_SW_BPF_OUTPUT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		.symbol = "bpf-output",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		.alias  = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) #define __PERF_EVENT_FIELD(config, name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) #define PERF_EVENT_RAW(config)		__PERF_EVENT_FIELD(config, RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) #define PERF_EVENT_CONFIG(config)	__PERF_EVENT_FIELD(config, CONFIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) #define PERF_EVENT_TYPE(config)		__PERF_EVENT_FIELD(config, TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) #define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) #define for_each_subsystem(sys_dir, sys_dirent)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	while ((sys_dirent = readdir(sys_dir)) != NULL)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		if (sys_dirent->d_type == DT_DIR &&		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		    (strcmp(sys_dirent->d_name, ".")) &&	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		    (strcmp(sys_dirent->d_name, "..")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	char evt_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	fd = open(evt_path, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) #define for_each_event(dir_path, evt_dir, evt_dirent)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	while ((evt_dirent = readdir(evt_dir)) != NULL)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		if (evt_dirent->d_type == DT_DIR &&		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		    (strcmp(evt_dirent->d_name, ".")) &&	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		    (strcmp(evt_dirent->d_name, "..")) &&	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		    (!tp_event_has_id(dir_path, evt_dirent)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) #define MAX_EVENT_LENGTH 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) void parse_events__handle_error(struct parse_events_error *err, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 				char *str, char *help)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	if (WARN(!str, "WARNING: failed to provide error string\n")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		free(help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	switch (err->num_errors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		err->idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		err->str = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		err->help = help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		err->first_idx = err->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		err->idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		err->first_str = err->str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		err->str = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		err->first_help = err->help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		err->help = help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		pr_debug("Multiple errors dropping message: %s (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 			err->str, err->help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		free(err->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		err->str = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		free(err->help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		err->help = help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	err->num_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) struct tracepoint_path *tracepoint_id_to_path(u64 config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	struct tracepoint_path *path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	DIR *sys_dir, *evt_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	struct dirent *sys_dirent, *evt_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	char id_buf[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	u64 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	char evt_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	char *dir_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	sys_dir = tracing_events__opendir();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	if (!sys_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	for_each_subsystem(sys_dir, sys_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		dir_path = get_events_file(sys_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		if (!dir_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		evt_dir = opendir(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		if (!evt_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		for_each_event(dir_path, evt_dir, evt_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 				  evt_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			fd = open(evt_path, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 			if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 			if (read(fd, id_buf, sizeof(id_buf)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 				close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 			close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 			id = atoll(id_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 			if (id == config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 				put_events_file(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 				closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 				closedir(sys_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 				path = zalloc(sizeof(*path));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 				if (!path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 					return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 				if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 					free(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 					return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 				if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 					zfree(&path->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 					free(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 					return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 				return path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		put_events_file(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	closedir(sys_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) struct tracepoint_path *tracepoint_name_to_path(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	struct tracepoint_path *path = zalloc(sizeof(*path));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	char *str = strchr(name, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	if (path == NULL || str == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		free(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	path->system = strndup(name, str - name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	path->name = strdup(str+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	if (path->system == NULL || path->name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		zfree(&path->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		zfree(&path->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		zfree(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	return path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) const char *event_type(int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	case PERF_TYPE_HARDWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		return "hardware";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	case PERF_TYPE_SOFTWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		return "software";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	case PERF_TYPE_TRACEPOINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		return "tracepoint";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	case PERF_TYPE_HW_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		return "hardware-cache";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) static int parse_events__is_name_term(struct parse_events_term *term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) static char *get_config_name(struct list_head *head_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	if (!head_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	list_for_each_entry(term, head_terms, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		if (parse_events__is_name_term(term))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 			return term->val.str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static struct evsel *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) __add_event(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	    struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	    bool init_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	    char *name, struct perf_pmu *pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	    struct list_head *config_terms, bool auto_merge_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	    const char *cpu_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 			       cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	if (init_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		event_attr_init(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	evsel = evsel__new_idx(attr, *idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	if (!evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		perf_cpu_map__put(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	(*idx)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	evsel->core.cpus = cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	evsel->core.own_cpus = perf_cpu_map__get(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	evsel->core.system_wide = pmu ? pmu->is_uncore : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	evsel->auto_merge_stats = auto_merge_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		evsel->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	if (config_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		list_splice(config_terms, &evsel->config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	if (list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		list_add_tail(&evsel->core.node, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	return evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 					char *name, struct perf_pmu *pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 			   NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) static int add_event(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		     struct perf_event_attr *attr, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		     struct list_head *config_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	return __add_event(list, idx, attr, true, name, NULL, config_terms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			   false, NULL) ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) static int add_event_tool(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			  enum perf_tool_event tool_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	struct perf_event_attr attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		.type = PERF_TYPE_SOFTWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		.config = PERF_COUNT_SW_DUMMY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	evsel = __add_event(list, idx, &attr, true, NULL, NULL, NULL, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 			    "0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (!evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	evsel->tool_event = tool_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	if (tool_event == PERF_TOOL_DURATION_TIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		evsel->unit = "ns";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) static int parse_aliases(char *str, const char *names[][EVSEL__MAX_ALIASES], int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	int n, longest = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		for (j = 0; j < EVSEL__MAX_ALIASES && names[i][j]; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			n = strlen(names[i][j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 			if (n > longest && !strncasecmp(str, names[i][j], n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				longest = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		if (longest > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) typedef int config_term_func_t(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			       struct parse_events_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			       struct parse_events_error *err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) static int config_term_common(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			      struct parse_events_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 			      struct parse_events_error *err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) static int config_attr(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		       struct list_head *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		       struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		       config_term_func_t config_term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) int parse_events_add_cache(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			   char *type, char *op_result1, char *op_result2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			   struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			   struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	LIST_HEAD(config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	char name[MAX_NAME_LEN], *config_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	int cache_type = -1, cache_op = -1, cache_result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	char *op_result[2] = { op_result1, op_result2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	 * No fallback - if we cannot get a clear cache type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	 * then bail out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	cache_type = parse_aliases(type, evsel__hw_cache, PERF_COUNT_HW_CACHE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	if (cache_type == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	config_name = get_config_name(head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	n = snprintf(name, MAX_NAME_LEN, "%s", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	for (i = 0; (i < 2) && (op_result[i]); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		char *str = op_result[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		if (cache_op == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			cache_op = parse_aliases(str, evsel__hw_cache_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 						 PERF_COUNT_HW_CACHE_OP_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			if (cache_op >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				if (!evsel__is_cache_op_valid(cache_type, cache_op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		if (cache_result == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			cache_result = parse_aliases(str, evsel__hw_cache_result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 						     PERF_COUNT_HW_CACHE_RESULT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			if (cache_result >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	 * Fall back to reads:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	if (cache_op == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		cache_op = PERF_COUNT_HW_CACHE_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	 * Fall back to accesses:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	if (cache_result == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	attr.config = cache_type | (cache_op << 8) | (cache_result << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	attr.type = PERF_TYPE_HW_CACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	if (head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		if (config_attr(&attr, head_config, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 				config_term_common))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		if (get_config_terms(head_config, &config_terms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	return add_event(list, idx, &attr, config_name ? : name, &config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static void tracepoint_error(struct parse_events_error *e, int err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 			     const char *sys, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	char help[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	 * We get error directly from syscall errno ( > 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	 * or from encoded pointer's error ( < 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	err = abs(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	case EACCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		str = "can't access trace events";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	case ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		str = "unknown tracepoint";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		str = "failed to add tracepoint";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	tracing_path__strerror_open_tp(err, help, sizeof(help), sys, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	parse_events__handle_error(e, 0, strdup(str), strdup(help));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) static int add_tracepoint(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 			  const char *sys_name, const char *evt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			  struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			  struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	struct evsel *evsel = evsel__newtp_idx(sys_name, evt_name, (*idx)++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	if (IS_ERR(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		tracepoint_error(err, PTR_ERR(evsel), sys_name, evt_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		return PTR_ERR(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		LIST_HEAD(config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		if (get_config_terms(head_config, &config_terms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		list_splice(&config_terms, &evsel->config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	list_add_tail(&evsel->core.node, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) static int add_tracepoint_multi_event(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 				      const char *sys_name, const char *evt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 				      struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 				      struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	char *evt_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	struct dirent *evt_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	DIR *evt_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	int ret = 0, found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	evt_path = get_events_file(sys_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (!evt_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		tracepoint_error(err, errno, sys_name, evt_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	evt_dir = opendir(evt_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	if (!evt_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		put_events_file(evt_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		tracepoint_error(err, errno, sys_name, evt_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	while (!ret && (evt_ent = readdir(evt_dir))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		if (!strcmp(evt_ent->d_name, ".")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		    || !strcmp(evt_ent->d_name, "..")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		    || !strcmp(evt_ent->d_name, "enable")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		    || !strcmp(evt_ent->d_name, "filter"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		if (!strglobmatch(evt_ent->d_name, evt_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		found++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 				     err, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		tracepoint_error(err, ENOENT, sys_name, evt_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	put_events_file(evt_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) static int add_tracepoint_event(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 				const char *sys_name, const char *evt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 				struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 				struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	return strpbrk(evt_name, "*?") ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	       add_tracepoint_multi_event(list, idx, sys_name, evt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 					  err, head_config) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	       add_tracepoint(list, idx, sys_name, evt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			      err, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				    const char *sys_name, const char *evt_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 				    struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				    struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	struct dirent *events_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	DIR *events_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	events_dir = tracing_events__opendir();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	if (!events_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		tracepoint_error(err, errno, sys_name, evt_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	while (!ret && (events_ent = readdir(events_dir))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		if (!strcmp(events_ent->d_name, ".")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		    || !strcmp(events_ent->d_name, "..")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		    || !strcmp(events_ent->d_name, "enable")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		    || !strcmp(events_ent->d_name, "header_event")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		    || !strcmp(events_ent->d_name, "header_page"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		if (!strglobmatch(events_ent->d_name, sys_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		ret = add_tracepoint_event(list, idx, events_ent->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 					   evt_name, err, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	closedir(events_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) struct __add_bpf_event_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	struct parse_events_state *parse_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	struct list_head *head_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			 void *_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	LIST_HEAD(new_evsels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	struct __add_bpf_event_param *param = _param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	struct parse_events_state *parse_state = param->parse_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	struct list_head *list = param->list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	struct evsel *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	 * Check if we should add the event, i.e. if it is a TP but starts with a '!',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	 * then don't add the tracepoint, this will be used for something else, like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	 * adding to a BPF_MAP_TYPE_PROG_ARRAY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	 * See tools/perf/examples/bpf/augmented_raw_syscalls.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	if (group[0] == '!')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	pr_debug("add bpf event %s:%s and attach bpf program %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		 group, event, fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	err = parse_events_add_tracepoint(&new_evsels, &parse_state->idx, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 					  event, parse_state->error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 					  param->head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		struct evsel *evsel, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		pr_debug("Failed to add BPF event %s:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			 group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		list_for_each_entry_safe(evsel, tmp, &new_evsels, core.node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			list_del_init(&evsel->core.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			evsel__delete(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	pr_debug("adding %s:%s\n", group, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	list_for_each_entry(pos, &new_evsels, core.node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		pr_debug("adding %s:%s to %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			 group, event, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		pos->bpf_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		pos->bpf_obj = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	list_splice(&new_evsels, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) int parse_events_load_bpf_obj(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			      struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			      struct bpf_object *obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			      struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	char errbuf[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	struct __add_bpf_event_param param = {parse_state, list, head_config};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	static bool registered_unprobe_atexit = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	if (IS_ERR(obj) || !obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		snprintf(errbuf, sizeof(errbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			 "Internal error: load bpf obj with NULL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	 * Register atexit handler before calling bpf__probe() so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	 * bpf__probe() don't need to unprobe probe points its already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	 * created when failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	if (!registered_unprobe_atexit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		atexit(bpf__clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		registered_unprobe_atexit = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	err = bpf__probe(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		bpf__strerror_probe(obj, err, errbuf, sizeof(errbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	err = bpf__load(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		bpf__strerror_load(obj, err, errbuf, sizeof(errbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	err = bpf__foreach_event(obj, add_bpf_event, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		snprintf(errbuf, sizeof(errbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			 "Attach events in BPF object failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	parse_events__handle_error(parse_state->error, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 				strdup(errbuf), strdup("(add -v to see detail)"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) parse_events_config_bpf(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			struct bpf_object *obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	int error_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	if (!head_config || list_empty(head_config))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	list_for_each_entry(term, head_config, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		if (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			parse_events__handle_error(parse_state->error, term->err_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 						strdup("Invalid config term for BPF object"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 						NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			char errbuf[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			bpf__strerror_config_obj(obj, term, parse_state->evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 						 &error_pos, err, errbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 						 sizeof(errbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 				idx = term->err_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 				idx = term->err_term + error_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			parse_events__handle_error(parse_state->error, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 						strdup(errbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 						strdup(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) "Hint:\tValid config terms:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) "     \tmap:[<arraymap>].value<indices>=[value]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) "     \tmap:[<eventmap>].event<indices>=[event]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) "     \twhere <indices> is something like [0,3...5] or [all]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) "     \t(add -v to see detail)"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829)  * Split config terms:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830)  * perf record -e bpf.c/call-graph=fp,map:array.value[0]=1/ ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831)  *  'call-graph=fp' is 'evt config', should be applied to each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832)  *  events in bpf.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833)  * 'map:array.value[0]=1' is 'obj config', should be processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834)  * with parse_events_config_bpf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  * Move object config terms from the first list to obj_head_config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) split_bpf_config_terms(struct list_head *evt_head_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		       struct list_head *obj_head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	struct parse_events_term *term, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	 * Currectly, all possible user config term
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	 * belong to bpf object. parse_events__is_hardcoded_term()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	 * happends to be a good flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	 * See parse_events_config_bpf() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	 * config_term_tracepoint().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	list_for_each_entry_safe(term, temp, evt_head_config, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		if (!parse_events__is_hardcoded_term(term))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			list_move_tail(&term->list, obj_head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) int parse_events_load_bpf(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			  struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			  char *bpf_file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			  bool source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			  struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	struct bpf_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	LIST_HEAD(obj_head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	if (head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		split_bpf_config_terms(head_config, &obj_head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	obj = bpf__prepare_load(bpf_file_name, source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	if (IS_ERR(obj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		char errbuf[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		err = PTR_ERR(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		if (err == -ENOTSUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 			snprintf(errbuf, sizeof(errbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 				 "BPF support is not compiled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			bpf__strerror_prepare_load(bpf_file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 						   source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 						   -err, errbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 						   sizeof(errbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		parse_events__handle_error(parse_state->error, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 					strdup(errbuf), strdup("(add -v to see detail)"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	err = parse_events_load_bpf_obj(parse_state, list, obj, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	err = parse_events_config_bpf(parse_state, obj, &obj_head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	 * Caller doesn't know anything about obj_head_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	 * so combine them together again before returnning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	if (head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		list_splice_tail(&obj_head_config, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		if (!type || !type[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) #define CHECK_SET_TYPE(bit)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) do {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	if (attr->bp_type & bit)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		return -EINVAL;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	else				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		attr->bp_type |= bit;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		switch (type[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 			CHECK_SET_TYPE(HW_BREAKPOINT_R);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		case 'w':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			CHECK_SET_TYPE(HW_BREAKPOINT_W);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			CHECK_SET_TYPE(HW_BREAKPOINT_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) #undef CHECK_SET_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	if (!attr->bp_type) /* Default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) int parse_events_add_breakpoint(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 				u64 addr, char *type, u64 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	attr.bp_addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	if (parse_breakpoint_type(type, &attr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	/* Provide some defaults if len is not specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		if (attr.bp_type == HW_BREAKPOINT_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 			len = sizeof(long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			len = HW_BREAKPOINT_LEN_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	attr.bp_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	attr.type = PERF_TYPE_BREAKPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	attr.sample_period = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	return add_event(list, idx, &attr, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) static int check_type_val(struct parse_events_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			  struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			  int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	if (type == term->type_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		parse_events__handle_error(err, term->err_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 					type == PARSE_EVENTS__TERM_TYPE_NUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 					? strdup("expected numeric value")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 					: strdup("expected string value"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 					NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)  * Update according to parse-events.l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	[PARSE_EVENTS__TERM_TYPE_USER]			= "<sysfs term>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	[PARSE_EVENTS__TERM_TYPE_CONFIG]		= "config",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	[PARSE_EVENTS__TERM_TYPE_CONFIG1]		= "config1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	[PARSE_EVENTS__TERM_TYPE_CONFIG2]		= "config2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	[PARSE_EVENTS__TERM_TYPE_NAME]			= "name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	[PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD]		= "period",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	[PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ]		= "freq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	[PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE]	= "branch_type",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	[PARSE_EVENTS__TERM_TYPE_TIME]			= "time",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	[PARSE_EVENTS__TERM_TYPE_CALLGRAPH]		= "call-graph",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	[PARSE_EVENTS__TERM_TYPE_STACKSIZE]		= "stack-size",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	[PARSE_EVENTS__TERM_TYPE_NOINHERIT]		= "no-inherit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	[PARSE_EVENTS__TERM_TYPE_INHERIT]		= "inherit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	[PARSE_EVENTS__TERM_TYPE_MAX_STACK]		= "max-stack",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	[PARSE_EVENTS__TERM_TYPE_MAX_EVENTS]		= "nr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	[PARSE_EVENTS__TERM_TYPE_OVERWRITE]		= "overwrite",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE]		= "no-overwrite",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	[PARSE_EVENTS__TERM_TYPE_DRV_CFG]		= "driver-config",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	[PARSE_EVENTS__TERM_TYPE_PERCORE]		= "percore",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	[PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT]		= "aux-output",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	[PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE]	= "aux-sample-size",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static bool config_term_shrinked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) config_term_avail(int term_type, struct parse_events_error *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	char *err_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (term_type < 0 || term_type >= __PARSE_EVENTS__TERM_TYPE_NR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		parse_events__handle_error(err, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 					strdup("Invalid term_type"), NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	if (!config_term_shrinked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	switch (term_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	case PARSE_EVENTS__TERM_TYPE_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	case PARSE_EVENTS__TERM_TYPE_CONFIG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	case PARSE_EVENTS__TERM_TYPE_CONFIG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	case PARSE_EVENTS__TERM_TYPE_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	case PARSE_EVENTS__TERM_TYPE_PERCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		/* term_type is validated so indexing is safe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		if (asprintf(&err_str, "'%s' is not usable in 'perf stat'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 				config_term_names[term_type]) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			parse_events__handle_error(err, -1, err_str, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) void parse_events__shrink_config_terms(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	config_term_shrinked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static int config_term_common(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			      struct parse_events_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			      struct parse_events_error *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) #define CHECK_TYPE_VAL(type)						   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) do {									   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (check_type_val(term, err, PARSE_EVENTS__TERM_TYPE_ ## type)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		return -EINVAL;						   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	switch (term->type_term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	case PARSE_EVENTS__TERM_TYPE_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		attr->config = term->val.num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	case PARSE_EVENTS__TERM_TYPE_CONFIG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		attr->config1 = term->val.num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	case PARSE_EVENTS__TERM_TYPE_CONFIG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		attr->config2 = term->val.num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		CHECK_TYPE_VAL(STR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		if (strcmp(term->val.str, "no") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		    parse_branch_str(term->val.str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 				    &attr->branch_sample_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			parse_events__handle_error(err, term->err_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 					strdup("invalid branch sample type"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 					NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	case PARSE_EVENTS__TERM_TYPE_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		if (term->val.num > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 			parse_events__handle_error(err, term->err_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 						strdup("expected 0 or 1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 						NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		CHECK_TYPE_VAL(STR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	case PARSE_EVENTS__TERM_TYPE_INHERIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	case PARSE_EVENTS__TERM_TYPE_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		CHECK_TYPE_VAL(STR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	case PARSE_EVENTS__TERM_TYPE_PERCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		if ((unsigned int)term->val.num > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 			parse_events__handle_error(err, term->err_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 						strdup("expected 0 or 1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 						NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		CHECK_TYPE_VAL(NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		if (term->val.num > UINT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			parse_events__handle_error(err, term->err_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 						strdup("too big"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 						NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		parse_events__handle_error(err, term->err_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 				strdup("unknown term"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 				parse_events_formats_error_string(NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	 * Check term availbility after basic checking so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	 * PARSE_EVENTS__TERM_TYPE_USER can be found and filtered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	 * If check availbility at the entry of this function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	 * user will see "'<sysfs term>' is not usable in 'perf stat'"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	 * if an invalid config term is provided for legacy events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	 * (for example, instructions/badterm/...), which is confusing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	if (!config_term_avail(term->type_term, err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) #undef CHECK_TYPE_VAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static int config_term_pmu(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 			   struct parse_events_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			   struct parse_events_error *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	    term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		 * Always succeed for sysfs terms, as we dont know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		 * at this point what type they need to have.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		return config_term_common(attr, term, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) static int config_term_tracepoint(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 				  struct parse_events_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 				  struct parse_events_error *err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	switch (term->type_term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	case PARSE_EVENTS__TERM_TYPE_INHERIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		return config_term_common(attr, term, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 			parse_events__handle_error(err, term->err_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 				strdup("unknown term"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 				strdup("valid terms: call-graph,stack-size\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static int config_attr(struct perf_event_attr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		       struct list_head *head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		       struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		       config_term_func_t config_term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	list_for_each_entry(term, head, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		if (config_term(attr, term, err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static int get_config_terms(struct list_head *head_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			    struct list_head *head_terms __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) #define ADD_CONFIG_TERM(__type, __weak)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	struct evsel_config_term *__t;			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	__t = zalloc(sizeof(*__t));				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	if (!__t)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		return -ENOMEM;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	INIT_LIST_HEAD(&__t->list);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	__t->type       = EVSEL__CONFIG_TERM_ ## __type;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	__t->weak	= __weak;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	list_add_tail(&__t->list, head_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) #define ADD_CONFIG_TERM_VAL(__type, __name, __val, __weak)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	ADD_CONFIG_TERM(__type, __weak);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	__t->val.__name = __val;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) #define ADD_CONFIG_TERM_STR(__type, __val, __weak)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	ADD_CONFIG_TERM(__type, __weak);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	__t->val.str = strdup(__val);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	if (!__t->val.str) {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		zfree(&__t);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		return -ENOMEM;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	}							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	__t->free_str = true;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	list_for_each_entry(term, head_config, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		switch (term->type_term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 			ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		case PARSE_EVENTS__TERM_TYPE_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			ADD_CONFIG_TERM_VAL(TIME, time, term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			ADD_CONFIG_TERM_STR(BRANCH, term->val.str, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 			ADD_CONFIG_TERM_VAL(STACK_USER, stack_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 					    term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		case PARSE_EVENTS__TERM_TYPE_INHERIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			ADD_CONFIG_TERM_VAL(INHERIT, inherit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 					    term->val.num ? 1 : 0, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			ADD_CONFIG_TERM_VAL(INHERIT, inherit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 					    term->val.num ? 0 : 1, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 			ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 					    term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 			ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 					    term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 			ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 					    term->val.num ? 1 : 0, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 			ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 					    term->val.num ? 0 : 1, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 			ADD_CONFIG_TERM_STR(DRV_CFG, term->val.str, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		case PARSE_EVENTS__TERM_TYPE_PERCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 			ADD_CONFIG_TERM_VAL(PERCORE, percore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 					    term->val.num ? true : false, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 			ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 					    term->val.num ? 1 : 0, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 			ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 					    term->val.num, term->weak);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)  * Add EVSEL__CONFIG_TERM_CFG_CHG where cfg_chg will have a bit set for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)  * each bit of attr->config that the user has changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int get_config_chgs(struct perf_pmu *pmu, struct list_head *head_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 			   struct list_head *head_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	u64 bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	list_for_each_entry(term, head_config, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		switch (term->type_term) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		case PARSE_EVENTS__TERM_TYPE_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 			type = perf_pmu__format_type(&pmu->format, term->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 			if (type != PERF_PMU_FORMAT_VALUE_CONFIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 			bits |= perf_pmu__format_bits(&pmu->format, term->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		case PARSE_EVENTS__TERM_TYPE_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 			bits = ~(u64)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	if (bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		ADD_CONFIG_TERM_VAL(CFG_CHG, cfg_chg, bits, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) #undef ADD_CONFIG_TERM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) int parse_events_add_tracepoint(struct list_head *list, int *idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 				const char *sys, const char *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 				struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 				struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	if (head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		if (config_attr(&attr, head_config, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 				config_term_tracepoint))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	if (strpbrk(sys, "*?"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		return add_tracepoint_multi_sys(list, idx, sys, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 						err, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		return add_tracepoint_event(list, idx, sys, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 					    err, head_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) int parse_events_add_numeric(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 			     struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 			     u32 type, u64 config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 			     struct list_head *head_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	LIST_HEAD(config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	attr.type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	attr.config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	if (head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		if (config_attr(&attr, head_config, parse_state->error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 				config_term_common))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		if (get_config_terms(head_config, &config_terms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	return add_event(list, &parse_state->idx, &attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 			 get_config_name(head_config), &config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) int parse_events_add_tool(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 			  struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			  enum perf_tool_event tool_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	return add_event_tool(list, &parse_state->idx, tool_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) static bool config_term_percore(struct list_head *config_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	struct evsel_config_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	list_for_each_entry(term, config_terms, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		if (term->type == EVSEL__CONFIG_TERM_PERCORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 			return term->val.percore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) int parse_events_add_pmu(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 			 struct list_head *list, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 			 struct list_head *head_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 			 bool auto_merge_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 			 bool use_alias)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	struct perf_pmu_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	struct perf_pmu *pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	struct parse_events_error *err = parse_state->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	bool use_uncore_alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	LIST_HEAD(config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	if (verbose > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		fprintf(stderr, "Attempting to add event pmu '%s' with '",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		if (head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 			struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 			list_for_each_entry(term, head_config, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 				fprintf(stderr, "%s,", term->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		fprintf(stderr, "' that may result in non-fatal errors\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	pmu = parse_state->fake_pmu ?: perf_pmu__find(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	if (!pmu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		char *err_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		if (asprintf(&err_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 				"Cannot find PMU `%s'. Missing kernel support?",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 				name) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 			parse_events__handle_error(err, 0, err_str, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	if (pmu->default_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		memcpy(&attr, pmu->default_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		       sizeof(struct perf_event_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	use_uncore_alias = (pmu->is_uncore && use_alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	if (!head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		attr.type = pmu->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		evsel = __add_event(list, &parse_state->idx, &attr, true, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 				    pmu, NULL, auto_merge_stats, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		if (evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 			evsel->pmu_name = name ? strdup(name) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 			evsel->use_uncore_alias = use_uncore_alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	if (verbose > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		fprintf(stderr, "After aliases, add event pmu '%s' with '",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 			name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 		if (head_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 			struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 			list_for_each_entry(term, head_config, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 				fprintf(stderr, "%s,", term->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		fprintf(stderr, "' that may result in non-fatal errors\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	 * Configure hardcoded terms first, no need to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	 * return value when called with fail == 0 ;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	if (config_attr(&attr, head_config, parse_state->error, config_term_pmu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	if (get_config_terms(head_config, &config_terms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	 * When using default config, record which bits of attr->config were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	 * changed by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	if (pmu->default_config && get_config_chgs(pmu, head_config, &config_terms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	if (!parse_state->fake_pmu && perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		struct evsel_config_term *pos, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		list_for_each_entry_safe(pos, tmp, &config_terms, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 			list_del_init(&pos->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 			if (pos->free_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 				zfree(&pos->val.str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 			free(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	evsel = __add_event(list, &parse_state->idx, &attr, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 			    get_config_name(head_config), pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 			    &config_terms, auto_merge_stats, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	if (!evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	evsel->pmu_name = name ? strdup(name) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	evsel->use_uncore_alias = use_uncore_alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	evsel->percore = config_term_percore(&evsel->config_terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	if (parse_state->fake_pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	evsel->unit = info.unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	evsel->scale = info.scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	evsel->per_pkg = info.per_pkg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	evsel->snapshot = info.snapshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	evsel->metric_expr = info.metric_expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	evsel->metric_name = info.metric_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 			       char *str, struct list_head **listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	struct perf_pmu *pmu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	int ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	*listp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	/* Add it for all PMUs that support the alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	list = malloc(sizeof(struct list_head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	INIT_LIST_HEAD(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		struct perf_pmu_alias *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		list_for_each_entry(alias, &pmu->aliases, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 			if (!strcasecmp(alias->name, str)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 				struct list_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 				char *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 				head = malloc(sizeof(struct list_head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 				if (!head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 					return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 				INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 				config = strdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 				if (!config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 					return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 				if (parse_events_term__num(&term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 						   PARSE_EVENTS__TERM_TYPE_USER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 						   config, 1, false, &config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 						   NULL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 					free(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 					free(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 					return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 				list_add_tail(&term->list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 				if (!parse_events_add_pmu(parse_state, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 							  pmu->name, head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 							  true, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 					pr_debug("%s -> %s/%s/\n", str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 						 pmu->name, alias->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 					ok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 				parse_events_terms__delete(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if (!ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		free(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	*listp = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) int parse_events__modifier_group(struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 				 char *event_mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	return parse_events__modifier_event(list, event_mod, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)  * Check if the two uncore PMUs are from the same uncore block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)  * The format of the uncore PMU name is uncore_#blockname_#pmuidx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) static bool is_same_uncore_block(const char *pmu_name_a, const char *pmu_name_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	char *end_a, *end_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	end_a = strrchr(pmu_name_a, '_');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	end_b = strrchr(pmu_name_b, '_');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	if (!end_a || !end_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	if ((end_a - pmu_name_a) != (end_b - pmu_name_b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	return (strncmp(pmu_name_a, pmu_name_b, end_a - pmu_name_a) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 					   struct parse_events_state *parse_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	struct evsel *evsel, *leader;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	uintptr_t *leaders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	bool is_leader = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	int i, nr_pmu = 0, total_members, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	leader = list_first_entry(list, struct evsel, core.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	evsel = list_last_entry(list, struct evsel, core.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	total_members = evsel->idx - leader->idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	leaders = calloc(total_members, sizeof(uintptr_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	if (WARN_ON(!leaders))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	 * Going through the whole group and doing sanity check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	 * All members must use alias, and be from the same uncore block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	 * Also, storing the leader events in an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	__evlist__for_each_entry(list, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 		/* Only split the uncore group which members use alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		if (!evsel->use_uncore_alias)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		/* The events must be from the same uncore block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		if (!is_same_uncore_block(leader->pmu_name, evsel->pmu_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		if (!is_leader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		 * If the event's PMU name starts to repeat, it must be a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		 * event. That can be used to distinguish the leader from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		 * other members, even they have the same event name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		if ((leader != evsel) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		    !strcmp(leader->pmu_name, evsel->pmu_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 			is_leader = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		/* Store the leader event for each PMU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		leaders[nr_pmu++] = (uintptr_t) evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	/* only one event alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	if (nr_pmu == total_members) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		parse_state->nr_groups--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 		goto handled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	 * An uncore event alias is a joint name which means the same event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	 * runs on all PMUs of a block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	 * Perf doesn't support mixed events from different PMUs in the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	 * group. The big group has to be split into multiple small groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	 * which only include the events from the same PMU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	 * Here the uncore event aliases must be from the same uncore block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	 * The number of PMUs must be same for each alias. The number of new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	 * small groups equals to the number of PMUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	 * Setting the leader event for corresponding members in each group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	__evlist__for_each_entry(list, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		if (i >= nr_pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 			i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		evsel->leader = (struct evsel *) leaders[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	/* The number of members and group name are same for each group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	for (i = 0; i < nr_pmu; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 		evsel = (struct evsel *) leaders[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		evsel->core.nr_members = total_members / nr_pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		evsel->group_name = name ? strdup(name) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	/* Take the new small groups into account */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	parse_state->nr_groups += nr_pmu - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) handled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	free(leaders);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) void parse_events__set_leader(char *name, struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 			      struct parse_events_state *parse_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	struct evsel *leader;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	if (list_empty(list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 		WARN_ONCE(true, "WARNING: failed to set leader: empty list");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	if (parse_events__set_leader_for_uncore_aliase(name, list, parse_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	__perf_evlist__set_leader(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	leader = list_entry(list->next, struct evsel, core.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	leader->group_name = name ? strdup(name) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) /* list_event is assumed to point to malloc'ed memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) void parse_events_update_lists(struct list_head *list_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			       struct list_head *list_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	 * Called for single event definition. Update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	 * 'all event' list, and reinit the 'single event'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	 * list, for next event definition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	list_splice_tail(list_event, list_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	free(list_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) struct event_modifier {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	int eu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	int ek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	int eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	int eH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	int eG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	int eI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	int precise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	int precise_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	int exclude_GH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	int sample_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	int pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	int weak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	int exclusive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static int get_event_modifier(struct event_modifier *mod, char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 			       struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	int eu = evsel ? evsel->core.attr.exclude_user : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	int ek = evsel ? evsel->core.attr.exclude_kernel : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	int eh = evsel ? evsel->core.attr.exclude_hv : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	int eH = evsel ? evsel->core.attr.exclude_host : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	int eG = evsel ? evsel->core.attr.exclude_guest : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	int eI = evsel ? evsel->core.attr.exclude_idle : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	int precise = evsel ? evsel->core.attr.precise_ip : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	int precise_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	int sample_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	int pinned = evsel ? evsel->core.attr.pinned : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	int exclusive = evsel ? evsel->core.attr.exclusive : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	int exclude = eu | ek | eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	int exclude_GH = evsel ? evsel->exclude_GH : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	int weak = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	memset(mod, 0, sizeof(*mod));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	while (*str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 		if (*str == 'u') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 			if (!exclude)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 				exclude = eu = ek = eh = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 			if (!exclude_GH && !perf_guest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 				eG = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 			eu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		} else if (*str == 'k') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 			if (!exclude)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 				exclude = eu = ek = eh = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 			ek = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		} else if (*str == 'h') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 			if (!exclude)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 				exclude = eu = ek = eh = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 			eh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		} else if (*str == 'G') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 			if (!exclude_GH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 				exclude_GH = eG = eH = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 			eG = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 		} else if (*str == 'H') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 			if (!exclude_GH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 				exclude_GH = eG = eH = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 			eH = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		} else if (*str == 'I') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 			eI = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		} else if (*str == 'p') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 			precise++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 			/* use of precise requires exclude_guest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 			if (!exclude_GH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 				eG = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		} else if (*str == 'P') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 			precise_max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 		} else if (*str == 'S') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 			sample_read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 		} else if (*str == 'D') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 			pinned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 		} else if (*str == 'e') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 			exclusive = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		} else if (*str == 'W') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 			weak = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		++str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	 * precise ip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	 *  0 - SAMPLE_IP can have arbitrary skid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	 *  1 - SAMPLE_IP must have constant skid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	 *  2 - SAMPLE_IP requested to have 0 skid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	 *  3 - SAMPLE_IP must have 0 skid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	 *  See also PERF_RECORD_MISC_EXACT_IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	if (precise > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	mod->eu = eu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	mod->ek = ek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	mod->eh = eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	mod->eH = eH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	mod->eG = eG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	mod->eI = eI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	mod->precise = precise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	mod->precise_max = precise_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	mod->exclude_GH = exclude_GH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	mod->sample_read = sample_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	mod->pinned = pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	mod->weak = weak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	mod->exclusive = exclusive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)  * Basic modifier sanity check to validate it contains only one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)  * instance of any modifier (apart from 'p') present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) static int check_modifier(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	char *p = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	/* The sizeof includes 0 byte as well. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	if (strlen(str) > (sizeof("ukhGHpppPSDIWe") - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		if (*p != 'p' && strchr(p + 1, *p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) int parse_events__modifier_event(struct list_head *list, char *str, bool add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	struct event_modifier mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	if (str == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	if (check_modifier(str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	if (!add && get_event_modifier(&mod, str, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	__evlist__for_each_entry(list, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		if (add && get_event_modifier(&mod, str, evsel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		evsel->core.attr.exclude_user   = mod.eu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		evsel->core.attr.exclude_kernel = mod.ek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		evsel->core.attr.exclude_hv     = mod.eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		evsel->core.attr.precise_ip     = mod.precise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 		evsel->core.attr.exclude_host   = mod.eH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		evsel->core.attr.exclude_guest  = mod.eG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 		evsel->core.attr.exclude_idle   = mod.eI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		evsel->exclude_GH          = mod.exclude_GH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		evsel->sample_read         = mod.sample_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		evsel->precise_max         = mod.precise_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 		evsel->weak_group	   = mod.weak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		if (evsel__is_group_leader(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 			evsel->core.attr.pinned = mod.pinned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 			evsel->core.attr.exclusive = mod.exclusive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) int parse_events_name(struct list_head *list, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	__evlist__for_each_entry(list, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		if (!evsel->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 			evsel->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) comp_pmu(const void *p1, const void *p2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	return strcasecmp(pmu1->symbol, pmu2->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static void perf_pmu__parse_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	if (perf_pmu_events_list_num > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 		struct perf_pmu_event_symbol *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		for (i = 0; i < perf_pmu_events_list_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 			p = perf_pmu_events_list + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 			zfree(&p->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		zfree(&perf_pmu_events_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		perf_pmu_events_list_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) #define SET_SYMBOL(str, stype)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) do {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	p->symbol = str;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	if (!p->symbol)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 		goto err;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	p->type = stype;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)  * Read the pmu events list from sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)  * Save it into perf_pmu_events_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static void perf_pmu__parse_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	struct perf_pmu *pmu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	struct perf_pmu_alias *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	pmu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		list_for_each_entry(alias, &pmu->aliases, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 			if (strchr(alias->name, '-'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 				len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	if (len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		perf_pmu_events_list_num = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	if (!perf_pmu_events_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	perf_pmu_events_list_num = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	pmu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		list_for_each_entry(alias, &pmu->aliases, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 			struct perf_pmu_event_symbol *p = perf_pmu_events_list + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 			char *tmp = strchr(alias->name, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 			if (tmp != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 				SET_SYMBOL(strndup(alias->name, tmp - alias->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 						PMU_EVENT_SYMBOL_PREFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 				p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 				SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 				len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 				SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 				len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	qsort(perf_pmu_events_list, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		sizeof(struct perf_pmu_event_symbol), comp_pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	perf_pmu__parse_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)  * This function injects special term in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)  * perf_pmu_events_list so the test code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)  * can check on this functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) int perf_pmu__test_parse_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	struct perf_pmu_event_symbol *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	list = malloc(sizeof(*list) * 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	list->type   = PMU_EVENT_SYMBOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	list->symbol = strdup("read");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	if (!list->symbol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 		free(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	perf_pmu_events_list = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	perf_pmu_events_list_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) enum perf_pmu_event_symbol_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) perf_pmu__parse_check(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	struct perf_pmu_event_symbol p, *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	/* scan kernel pmu events from sysfs if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	if (perf_pmu_events_list_num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 		perf_pmu__parse_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	 * name "cpu" could be prefix of cpu-cycles or cpu// events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	 * cpu-cycles has been handled by hardcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	 * So it must be cpu// events, not kernel pmu event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		return PMU_EVENT_SYMBOL_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	p.symbol = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	r = bsearch(&p, perf_pmu_events_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 			(size_t) perf_pmu_events_list_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 			sizeof(struct perf_pmu_event_symbol), comp_pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	zfree(&p.symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	return r ? r->type : PMU_EVENT_SYMBOL_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) static int parse_events__scanner(const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 				 struct parse_events_state *parse_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	YY_BUFFER_STATE buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	void *scanner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	ret = parse_events_lex_init_extra(parse_state, &scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	buffer = parse_events__scan_string(str, scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) #ifdef PARSER_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	parse_events_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	parse_events_set_debug(1, scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	ret = parse_events_parse(parse_state, scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	parse_events__flush_buffer(buffer, scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	parse_events__delete_buffer(buffer, scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	parse_events_lex_destroy(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)  * parse event config string, return a list of event terms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) int parse_events_terms(struct list_head *terms, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	struct parse_events_state parse_state = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 		.terms  = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 		.stoken = PE_START_TERMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	ret = parse_events__scanner(str, &parse_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	perf_pmu__parse_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 		list_splice(parse_state.terms, terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 		zfree(&parse_state.terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	parse_events_terms__delete(parse_state.terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) int __parse_events(struct evlist *evlist, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		   struct parse_events_error *err, struct perf_pmu *fake_pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	struct parse_events_state parse_state = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		.list	  = LIST_HEAD_INIT(parse_state.list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		.idx	  = evlist->core.nr_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		.error	  = err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		.evlist	  = evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 		.stoken	  = PE_START_EVENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		.fake_pmu = fake_pmu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	ret = parse_events__scanner(str, &parse_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	perf_pmu__parse_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	if (!ret && list_empty(&parse_state.list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		WARN_ONCE(true, "WARNING: event parser found nothing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	 * Add list to the evlist even with errors to allow callers to clean up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	perf_evlist__splice_list_tail(evlist, &parse_state.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 		struct evsel *last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 		evlist->nr_groups += parse_state.nr_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		last = evlist__last(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 		last->cmdline_group_boundary = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	 * There are 2 users - builtin-record and builtin-test objects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	 * Both call evlist__delete in case of error, so we dont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	 * need to bother.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) #define MAX_WIDTH 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) static int get_term_width(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	struct winsize ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	get_term_dimensions(&ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) static void __parse_events_print_error(int err_idx, const char *err_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 				const char *err_help, const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	const char *str = "invalid or unsupported event: ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	char _buf[MAX_WIDTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	char *buf = (char *) event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	if (err_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 		/* -2 for extra '' in the final fprintf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 		int width       = get_term_width() - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		int len_event   = strlen(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		int len_str, max_len, cut = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		 * Maximum error index indent, we will cut
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		 * the event string if it's bigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 		int max_err_idx = 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		 * Let's be specific with the message when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		 * we have the precise error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 		str     = "event syntax error: ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		len_str = strlen(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 		max_len = width - len_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 		buf = _buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		/* We're cutting from the beginning. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 		if (err_idx > max_err_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 			cut = err_idx - max_err_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 		strncpy(buf, event + cut, max_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 		/* Mark cut parts with '..' on both sides. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		if (cut)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 			buf[0] = buf[1] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 		if ((len_event - cut) > max_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 			buf[max_len - 1] = buf[max_len - 2] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 			buf[max_len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		idx = len_str + err_idx - cut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	fprintf(stderr, "%s'%s'\n", str, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	if (idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		if (err_help)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 			fprintf(stderr, "\n%s\n", err_help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) void parse_events_print_error(struct parse_events_error *err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 			      const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	if (!err->num_errors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	__parse_events_print_error(err->idx, err->str, err->help, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	zfree(&err->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	zfree(&err->help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	if (err->num_errors > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 		fputs("\nInitial error:\n", stderr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 		__parse_events_print_error(err->first_idx, err->first_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 					err->first_help, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		zfree(&err->first_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 		zfree(&err->first_help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) #undef MAX_WIDTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) int parse_events_option(const struct option *opt, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 			int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	struct evlist *evlist = *(struct evlist **)opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	struct parse_events_error err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	bzero(&err, sizeof(err));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	ret = parse_events(evlist, str, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 		parse_events_print_error(&err, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 		fprintf(stderr, "Run 'perf list' for a list of valid events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	struct evlist **evlistp = opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	if (*evlistp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		*evlistp = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 		if (*evlistp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 			fprintf(stderr, "Not enough memory to create evlist\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	ret = parse_events_option(opt, str, unset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		evlist__delete(*evlistp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 		*evlistp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) foreach_evsel_in_last_glob(struct evlist *evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 			   int (*func)(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 				       const void *arg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 			   const void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	struct evsel *last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	 * Don't return when list_empty, give func a chance to report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	 * error when it found last == NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	 * So no need to WARN here, let *func do this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	if (evlist->core.nr_entries > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 		last = evlist__last(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		err = (*func)(last, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		if (!last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 		if (last->core.node.prev == &evlist->core.entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		last = list_entry(last->core.node.prev, struct evsel, core.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	} while (!last->cmdline_group_boundary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) static int set_filter(struct evsel *evsel, const void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	const char *str = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	int nr_addr_filters = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	struct perf_pmu *pmu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	if (evsel == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 			"--filter option should follow a -e tracepoint or HW tracer option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 		if (evsel__append_tp_filter(evsel, str) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 			fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 				"not enough memory to hold filter string\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	while ((pmu = perf_pmu__scan(pmu)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 		if (pmu->type == evsel->core.attr.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		perf_pmu__scan_file(pmu, "nr_addr_filters",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 				    "%d", &nr_addr_filters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	if (!nr_addr_filters) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 			"This CPU does not support address filtering\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	if (evsel__append_addr_filter(evsel, str) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 			"not enough memory to hold filter string\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) int parse_filter(const struct option *opt, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 		 int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	struct evlist *evlist = *(struct evlist **)opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	return foreach_evsel_in_last_glob(evlist, set_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 					  (const void *)str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static int add_exclude_perf_filter(struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 				   const void *arg __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	char new_filter[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	if (evsel == NULL || evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 			"--exclude-perf option should follow a -e tracepoint option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	snprintf(new_filter, sizeof(new_filter), "common_pid != %d", getpid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	if (evsel__append_tp_filter(evsel, new_filter) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 			"not enough memory to hold filter string\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) int exclude_perf(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		 const char *arg __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		 int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	struct evlist *evlist = *(struct evlist **)opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 					  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) static const char * const event_type_descriptors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	"Hardware event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	"Software event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	"Tracepoint event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	"Hardware cache event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	"Raw hardware event descriptor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	"Hardware breakpoint",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) static int cmp_string(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	const char * const *as = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	const char * const *bs = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	return strcmp(*as, *bs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)  * Print the events from <debugfs_mount_point>/tracing/events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 			     bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	DIR *sys_dir, *evt_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	struct dirent *sys_dirent, *evt_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	char evt_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	char *dir_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	char **evt_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	unsigned int evt_i = 0, evt_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	bool evt_num_known = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	sys_dir = tracing_events__opendir();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	if (!sys_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	if (evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 		evt_list = zalloc(sizeof(char *) * evt_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 		if (!evt_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 			goto out_close_sys_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	for_each_subsystem(sys_dir, sys_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 		if (subsys_glob != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		    !strglobmatch(sys_dirent->d_name, subsys_glob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		dir_path = get_events_file(sys_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		if (!dir_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		evt_dir = opendir(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		if (!evt_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		for_each_event(dir_path, evt_dir, evt_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 			if (event_glob != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 			    !strglobmatch(evt_dirent->d_name, event_glob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 			if (!evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 				evt_num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 				 sys_dirent->d_name, evt_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 			evt_list[evt_i] = strdup(evt_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 			if (evt_list[evt_i] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 				put_events_file(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 				goto out_close_evt_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 			evt_i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 		closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		put_events_file(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	closedir(sys_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	if (!evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		evt_num_known = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 		goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	evt_i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	while (evt_i < evt_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 		if (name_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 			printf("%s ", evt_list[evt_i++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		printf("  %-50s [%s]\n", evt_list[evt_i++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	if (evt_num && pager_in_use())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 		printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	evt_num = evt_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	for (evt_i = 0; evt_i < evt_num; evt_i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		zfree(&evt_list[evt_i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	zfree(&evt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) out_close_evt_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) out_close_sys_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	closedir(sys_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	printf("FATAL: not enough memory to print %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 			event_type_descriptors[PERF_TYPE_TRACEPOINT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	if (evt_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)  * Check whether event is in <debugfs_mount_point>/tracing/events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) int is_valid_tracepoint(const char *event_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	DIR *sys_dir, *evt_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	struct dirent *sys_dirent, *evt_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	char evt_path[MAXPATHLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	char *dir_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	sys_dir = tracing_events__opendir();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	if (!sys_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	for_each_subsystem(sys_dir, sys_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		dir_path = get_events_file(sys_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		if (!dir_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 		evt_dir = opendir(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		if (!evt_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 			goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 		for_each_event(dir_path, evt_dir, evt_dirent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 				 sys_dirent->d_name, evt_dirent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 			if (!strcmp(evt_path, event_string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 				closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 				closedir(sys_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 		closedir(evt_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 		put_events_file(dir_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	closedir(sys_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) static bool is_event_supported(u8 type, unsigned config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	bool ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	int open_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	struct perf_event_attr attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		.type = type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 		.config = config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 		.disabled = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	struct perf_thread_map *tmap = thread_map__new_by_tid(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	if (tmap == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	evsel = evsel__new(&attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	if (evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		open_return = evsel__open(evsel, NULL, tmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 		ret = open_return >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 		if (open_return == -EACCES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 			 * This happens if the paranoid value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 			 * /proc/sys/kernel/perf_event_paranoid is set to 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 			 * Re-run with exclude_kernel set; we don't do that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			 * by default as some ARM machines do not support it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 			 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 			evsel->core.attr.exclude_kernel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 			ret = evsel__open(evsel, NULL, tmap) >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 		evsel__delete(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	perf_thread_map__put(tmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) void print_sdt_events(const char *subsys_glob, const char *event_glob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 		      bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	struct probe_cache *pcache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	struct probe_cache_entry *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	struct strlist *bidlist, *sdtlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	struct strlist_config cfg = {.dont_dupstr = true};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	struct str_node *nd, *nd2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	char *buf, *path, *ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	bool show_detail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	sdtlist = strlist__new(NULL, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	if (!sdtlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		pr_debug("Failed to allocate new strlist for SDT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	bidlist = build_id_cache__list_all(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	if (!bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		pr_debug("Failed to get buildids: %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	strlist__for_each_entry(nd, bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 		pcache = probe_cache__new(nd->s, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 		if (!pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		list_for_each_entry(ent, &pcache->entries, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 			if (!ent->sdt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 			if (subsys_glob &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 			    !strglobmatch(ent->pev.group, subsys_glob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 			if (event_glob &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 			    !strglobmatch(ent->pev.event, event_glob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 			ret = asprintf(&buf, "%s:%s@%s", ent->pev.group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 					ent->pev.event, nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 			if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 				strlist__add(sdtlist, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		probe_cache__delete(pcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	strlist__delete(bidlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	strlist__for_each_entry(nd, sdtlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		buf = strchr(nd->s, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 			*(buf++) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		if (name_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 			printf("%s ", nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		nd2 = strlist__next(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		if (nd2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 			ptr = strchr(nd2->s, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 			if (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 				*ptr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 			if (strcmp(nd->s, nd2->s) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 				show_detail = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		if (show_detail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 			path = build_id_cache__origname(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 			ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 			if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 				printf("  %-50s [%s]\n", buf, "SDT event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 				free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 			free(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 			printf("  %-50s [%s]\n", nd->s, "SDT event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		if (nd2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 			if (strcmp(nd->s, nd2->s) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 				show_detail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			if (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 				*ptr = '@';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	strlist__delete(sdtlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) int print_hwcache_events(const char *event_glob, bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	unsigned int type, op, i, evt_i = 0, evt_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	char name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	char **evt_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 	bool evt_num_known = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	if (evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		evt_list = zalloc(sizeof(char *) * evt_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 		if (!evt_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			goto out_enomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 	for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 		for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 			/* skip invalid cache type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 			if (!evsel__is_cache_op_valid(type, op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 			for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 				__evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 				if (event_glob != NULL && !strglobmatch(name, event_glob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 				if (!is_event_supported(PERF_TYPE_HW_CACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 							type | (op << 8) | (i << 16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 				if (!evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 					evt_num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 				evt_list[evt_i] = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 				if (evt_list[evt_i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 					goto out_enomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 				evt_i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	if (!evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		evt_num_known = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	evt_i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	while (evt_i < evt_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 		if (name_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 			printf("%s ", evt_list[evt_i++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		printf("  %-50s [%s]\n", evt_list[evt_i++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 				event_type_descriptors[PERF_TYPE_HW_CACHE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	if (evt_num && pager_in_use())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	evt_num = evt_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	for (evt_i = 0; evt_i < evt_num; evt_i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		zfree(&evt_list[evt_i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	zfree(&evt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	return evt_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) out_enomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	if (evt_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	return evt_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) static void print_tool_event(const char *name, const char *event_glob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 			     bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	if (event_glob && !strglobmatch(name, event_glob))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	if (name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		printf("%s ", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		printf("  %-50s [%s]\n", name, "Tool event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) void print_tool_events(const char *event_glob, bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	print_tool_event("duration_time", event_glob, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	if (pager_in_use())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 		printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) void print_symbol_events(const char *event_glob, unsigned type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 				struct event_symbol *syms, unsigned max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 				bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	unsigned int i, evt_i = 0, evt_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	char name[MAX_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	char **evt_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	bool evt_num_known = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	if (evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 		evt_list = zalloc(sizeof(char *) * evt_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 		if (!evt_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 			goto out_enomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		syms -= max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	for (i = 0; i < max; i++, syms++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 		if (event_glob != NULL && syms->symbol != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		    !(strglobmatch(syms->symbol, event_glob) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 		      (syms->alias && strglobmatch(syms->alias, event_glob))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 		if (!is_event_supported(type, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		if (!evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 			evt_num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		if (!name_only && strlen(syms->alias))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 			strlcpy(name, syms->symbol, MAX_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		evt_list[evt_i] = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		if (evt_list[evt_i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 			goto out_enomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		evt_i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	if (!evt_num_known) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		evt_num_known = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 		goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 	qsort(evt_list, evt_num, sizeof(char *), cmp_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	evt_i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	while (evt_i < evt_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 		if (name_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 			printf("%s ", evt_list[evt_i++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		printf("  %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	if (evt_num && pager_in_use())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	evt_num = evt_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	for (evt_i = 0; evt_i < evt_num; evt_i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		zfree(&evt_list[evt_i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	zfree(&evt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) out_enomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	if (evt_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)  * Print the help text for the event symbols:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) void print_events(const char *event_glob, bool name_only, bool quiet_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 			bool long_desc, bool details_flag, bool deprecated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 			    event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 			    event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	print_tool_events(event_glob, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	print_hwcache_events(event_glob, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	print_pmu_events(event_glob, name_only, quiet_flag, long_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 			details_flag, deprecated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	if (event_glob != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	if (!name_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 		printf("  %-50s [%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		       "rNNN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 		       event_type_descriptors[PERF_TYPE_RAW]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		printf("  %-50s [%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		       "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		       event_type_descriptors[PERF_TYPE_RAW]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 		if (pager_in_use())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 			printf("   (see 'man perf-list' on how to encode it)\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		printf("  %-50s [%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 		       "mem:<addr>[/len][:access]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 			event_type_descriptors[PERF_TYPE_BREAKPOINT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		if (pager_in_use())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 			printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	print_tracepoint_events(NULL, NULL, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	print_sdt_events(NULL, NULL, name_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	metricgroup__print(true, true, NULL, name_only, details_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	print_libpfm_events(name_only, long_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) int parse_events__is_hardcoded_term(struct parse_events_term *term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 	return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) static int new_term(struct parse_events_term **_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		    struct parse_events_term *temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		    char *str, u64 num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	struct parse_events_term *term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	term = malloc(sizeof(*term));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	if (!term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	*term = *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	INIT_LIST_HEAD(&term->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	term->weak = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	switch (term->type_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	case PARSE_EVENTS__TERM_TYPE_NUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 		term->val.num = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	case PARSE_EVENTS__TERM_TYPE_STR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		term->val.str = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		free(term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	*_term = term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) int parse_events_term__num(struct parse_events_term **term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 			   int type_term, char *config, u64 num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 			   bool no_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 			   void *loc_term_, void *loc_val_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	YYLTYPE *loc_term = loc_term_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 	YYLTYPE *loc_val = loc_val_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	struct parse_events_term temp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 		.type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		.type_term = type_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 		.config    = config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 		.no_value  = no_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 		.err_term  = loc_term ? loc_term->first_column : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		.err_val   = loc_val  ? loc_val->first_column  : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	return new_term(term, &temp, NULL, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) int parse_events_term__str(struct parse_events_term **term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 			   int type_term, char *config, char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 			   void *loc_term_, void *loc_val_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	YYLTYPE *loc_term = loc_term_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	YYLTYPE *loc_val = loc_val_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	struct parse_events_term temp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		.type_val  = PARSE_EVENTS__TERM_TYPE_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 		.type_term = type_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 		.config    = config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 		.err_term  = loc_term ? loc_term->first_column : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 		.err_val   = loc_val  ? loc_val->first_column  : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	return new_term(term, &temp, str, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) int parse_events_term__sym_hw(struct parse_events_term **term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 			      char *config, unsigned idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	struct event_symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	struct parse_events_term temp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 		.type_val  = PARSE_EVENTS__TERM_TYPE_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 		.type_term = PARSE_EVENTS__TERM_TYPE_USER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 		.config    = config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	if (!temp.config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 		temp.config = strdup("event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 		if (!temp.config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	BUG_ON(idx >= PERF_COUNT_HW_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	sym = &event_symbols_hw[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	str = strdup(sym->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	return new_term(term, &temp, str, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) int parse_events_term__clone(struct parse_events_term **new,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 			     struct parse_events_term *term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	struct parse_events_term temp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		.type_val  = term->type_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		.type_term = term->type_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 		.config    = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		.err_term  = term->err_term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 		.err_val   = term->err_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	if (term->config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		temp.config = strdup(term->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 		if (!temp.config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 		return new_term(new, &temp, NULL, term->val.num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	str = strdup(term->val.str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	return new_term(new, &temp, str, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) void parse_events_term__delete(struct parse_events_term *term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	if (term->array.nr_ranges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		zfree(&term->array.ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 	if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 		zfree(&term->val.str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 	zfree(&term->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	free(term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) int parse_events_copy_term_list(struct list_head *old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 				 struct list_head **new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	struct parse_events_term *term, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	if (!old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 		*new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	*new = malloc(sizeof(struct list_head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	if (!*new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 	INIT_LIST_HEAD(*new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	list_for_each_entry (term, old, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		ret = parse_events_term__clone(&n, term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		list_add_tail(&n->list, *new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) void parse_events_terms__purge(struct list_head *terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	struct parse_events_term *term, *h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	list_for_each_entry_safe(term, h, terms, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		list_del_init(&term->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 		parse_events_term__delete(term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) void parse_events_terms__delete(struct list_head *terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	if (!terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	parse_events_terms__purge(terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	free(terms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) void parse_events__clear_array(struct parse_events_array *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	zfree(&a->ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) void parse_events_evlist_error(struct parse_events_state *parse_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 			       int idx, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	if (!parse_state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	parse_events__handle_error(parse_state->error, idx, strdup(str), NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) static void config_terms_list(char *buf, size_t buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	bool first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	buf[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	for (i = 0; i < __PARSE_EVENTS__TERM_TYPE_NR; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		const char *name = config_term_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		if (!config_term_avail(i, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 		if (name[0] == '<')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 		if (strlen(buf) + strlen(name) + 2 >= buf_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		if (!first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 			strcat(buf, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 			first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 		strcat(buf, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135)  * Return string contains valid config terms of an event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)  * @additional_terms: For terms such as PMU sysfs terms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) char *parse_events_formats_error_string(char *additional_terms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	/* "no-overwrite" is the longest name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	char static_terms[__PARSE_EVENTS__TERM_TYPE_NR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 			  (sizeof("no-overwrite") - 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	config_terms_list(static_terms, sizeof(static_terms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	/* valid terms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	if (additional_terms) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		if (asprintf(&str, "valid terms: %s,%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 			     additional_terms, static_terms) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		if (asprintf(&str, "valid terms: %s", static_terms) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) }