162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __PERF_EVSEL_H
362306a36Sopenharmony_ci#define __PERF_EVSEL_H 1
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/list.h>
662306a36Sopenharmony_ci#include <stdbool.h>
762306a36Sopenharmony_ci#include <sys/types.h>
862306a36Sopenharmony_ci#include <linux/perf_event.h>
962306a36Sopenharmony_ci#include <linux/types.h>
1062306a36Sopenharmony_ci#include <internal/evsel.h>
1162306a36Sopenharmony_ci#include <perf/evsel.h>
1262306a36Sopenharmony_ci#include "symbol_conf.h"
1362306a36Sopenharmony_ci#include "pmus.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct bpf_object;
1662306a36Sopenharmony_cistruct cgroup;
1762306a36Sopenharmony_cistruct perf_counts;
1862306a36Sopenharmony_cistruct perf_stat_evsel;
1962306a36Sopenharmony_ciunion perf_event;
2062306a36Sopenharmony_cistruct bpf_counter_ops;
2162306a36Sopenharmony_cistruct target;
2262306a36Sopenharmony_cistruct hashmap;
2362306a36Sopenharmony_cistruct bperf_leader_bpf;
2462306a36Sopenharmony_cistruct bperf_follower_bpf;
2562306a36Sopenharmony_cistruct perf_pmu;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_citypedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cienum perf_tool_event {
3062306a36Sopenharmony_ci	PERF_TOOL_NONE		= 0,
3162306a36Sopenharmony_ci	PERF_TOOL_DURATION_TIME = 1,
3262306a36Sopenharmony_ci	PERF_TOOL_USER_TIME = 2,
3362306a36Sopenharmony_ci	PERF_TOOL_SYSTEM_TIME = 3,
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	PERF_TOOL_MAX,
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciconst char *perf_tool_event__to_str(enum perf_tool_event ev);
3962306a36Sopenharmony_cienum perf_tool_event perf_tool_event__from_str(const char *str);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define perf_tool_event__for_each_event(ev)		\
4262306a36Sopenharmony_ci	for ((ev) = PERF_TOOL_DURATION_TIME; (ev) < PERF_TOOL_MAX; ev++)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/** struct evsel - event selector
4562306a36Sopenharmony_ci *
4662306a36Sopenharmony_ci * @evlist - evlist this evsel is in, if it is in one.
4762306a36Sopenharmony_ci * @core - libperf evsel object
4862306a36Sopenharmony_ci * @name - Can be set to retain the original event name passed by the user,
4962306a36Sopenharmony_ci *         so that when showing results in tools such as 'perf stat', we
5062306a36Sopenharmony_ci *         show the name used, not some alias.
5162306a36Sopenharmony_ci * @id_pos: the position of the event id (PERF_SAMPLE_ID or
5262306a36Sopenharmony_ci *          PERF_SAMPLE_IDENTIFIER) in a sample event i.e. in the array of
5362306a36Sopenharmony_ci *          struct perf_record_sample
5462306a36Sopenharmony_ci * @is_pos: the position (counting backwards) of the event id (PERF_SAMPLE_ID or
5562306a36Sopenharmony_ci *          PERF_SAMPLE_IDENTIFIER) in a non-sample event i.e. if sample_id_all
5662306a36Sopenharmony_ci *          is used there is an id sample appended to non-sample events
5762306a36Sopenharmony_ci * @priv:   And what is in its containing unnamed union are tool specific
5862306a36Sopenharmony_ci */
5962306a36Sopenharmony_cistruct evsel {
6062306a36Sopenharmony_ci	struct perf_evsel	core;
6162306a36Sopenharmony_ci	struct evlist		*evlist;
6262306a36Sopenharmony_ci	off_t			id_offset;
6362306a36Sopenharmony_ci	int			id_pos;
6462306a36Sopenharmony_ci	int			is_pos;
6562306a36Sopenharmony_ci	unsigned int		sample_size;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	/*
6862306a36Sopenharmony_ci	 * These fields can be set in the parse-events code or similar.
6962306a36Sopenharmony_ci	 * Please check evsel__clone() to copy them properly so that
7062306a36Sopenharmony_ci	 * they can be released properly.
7162306a36Sopenharmony_ci	 */
7262306a36Sopenharmony_ci	struct {
7362306a36Sopenharmony_ci		char			*name;
7462306a36Sopenharmony_ci		char			*group_name;
7562306a36Sopenharmony_ci		const char		*pmu_name;
7662306a36Sopenharmony_ci		const char		*group_pmu_name;
7762306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
7862306a36Sopenharmony_ci		struct tep_event	*tp_format;
7962306a36Sopenharmony_ci#endif
8062306a36Sopenharmony_ci		char			*filter;
8162306a36Sopenharmony_ci		unsigned long		max_events;
8262306a36Sopenharmony_ci		double			scale;
8362306a36Sopenharmony_ci		const char		*unit;
8462306a36Sopenharmony_ci		struct cgroup		*cgrp;
8562306a36Sopenharmony_ci		const char		*metric_id;
8662306a36Sopenharmony_ci		enum perf_tool_event	tool_event;
8762306a36Sopenharmony_ci		/* parse modifier helper */
8862306a36Sopenharmony_ci		int			exclude_GH;
8962306a36Sopenharmony_ci		int			sample_read;
9062306a36Sopenharmony_ci		bool			snapshot;
9162306a36Sopenharmony_ci		bool			per_pkg;
9262306a36Sopenharmony_ci		bool			percore;
9362306a36Sopenharmony_ci		bool			precise_max;
9462306a36Sopenharmony_ci		bool			is_libpfm_event;
9562306a36Sopenharmony_ci		bool			auto_merge_stats;
9662306a36Sopenharmony_ci		bool			collect_stat;
9762306a36Sopenharmony_ci		bool			weak_group;
9862306a36Sopenharmony_ci		bool			bpf_counter;
9962306a36Sopenharmony_ci		bool			use_config_name;
10062306a36Sopenharmony_ci		bool			skippable;
10162306a36Sopenharmony_ci		int			bpf_fd;
10262306a36Sopenharmony_ci		struct bpf_object	*bpf_obj;
10362306a36Sopenharmony_ci		struct list_head	config_terms;
10462306a36Sopenharmony_ci	};
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	/*
10762306a36Sopenharmony_ci	 * metric fields are similar, but needs more care as they can have
10862306a36Sopenharmony_ci	 * references to other metric (evsel).
10962306a36Sopenharmony_ci	 */
11062306a36Sopenharmony_ci	struct evsel		**metric_events;
11162306a36Sopenharmony_ci	struct evsel		*metric_leader;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	void			*handler;
11462306a36Sopenharmony_ci	struct perf_counts	*counts;
11562306a36Sopenharmony_ci	struct perf_counts	*prev_raw_counts;
11662306a36Sopenharmony_ci	unsigned long		nr_events_printed;
11762306a36Sopenharmony_ci	struct perf_stat_evsel  *stats;
11862306a36Sopenharmony_ci	void			*priv;
11962306a36Sopenharmony_ci	u64			db_id;
12062306a36Sopenharmony_ci	bool			uniquified_name;
12162306a36Sopenharmony_ci	bool 			supported;
12262306a36Sopenharmony_ci	bool 			needs_swap;
12362306a36Sopenharmony_ci	bool 			disabled;
12462306a36Sopenharmony_ci	bool			no_aux_samples;
12562306a36Sopenharmony_ci	bool			immediate;
12662306a36Sopenharmony_ci	bool			tracking;
12762306a36Sopenharmony_ci	bool			ignore_missing_thread;
12862306a36Sopenharmony_ci	bool			forced_leader;
12962306a36Sopenharmony_ci	bool			cmdline_group_boundary;
13062306a36Sopenharmony_ci	bool			merged_stat;
13162306a36Sopenharmony_ci	bool			reset_group;
13262306a36Sopenharmony_ci	bool			errored;
13362306a36Sopenharmony_ci	bool			needs_auxtrace_mmap;
13462306a36Sopenharmony_ci	bool			default_metricgroup; /* A member of the Default metricgroup */
13562306a36Sopenharmony_ci	struct hashmap		*per_pkg_mask;
13662306a36Sopenharmony_ci	int			err;
13762306a36Sopenharmony_ci	struct {
13862306a36Sopenharmony_ci		evsel__sb_cb_t	*cb;
13962306a36Sopenharmony_ci		void		*data;
14062306a36Sopenharmony_ci	} side_band;
14162306a36Sopenharmony_ci	/*
14262306a36Sopenharmony_ci	 * For reporting purposes, an evsel sample can have a callchain
14362306a36Sopenharmony_ci	 * synthesized from AUX area data. Keep track of synthesized sample
14462306a36Sopenharmony_ci	 * types here. Note, the recorded sample_type cannot be changed because
14562306a36Sopenharmony_ci	 * it is needed to continue to parse events.
14662306a36Sopenharmony_ci	 * See also evsel__has_callchain().
14762306a36Sopenharmony_ci	 */
14862306a36Sopenharmony_ci	__u64			synth_sample_type;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	/*
15162306a36Sopenharmony_ci	 * bpf_counter_ops serves two use cases:
15262306a36Sopenharmony_ci	 *   1. perf-stat -b          counting events used byBPF programs
15362306a36Sopenharmony_ci	 *   2. perf-stat --use-bpf   use BPF programs to aggregate counts
15462306a36Sopenharmony_ci	 */
15562306a36Sopenharmony_ci	struct bpf_counter_ops	*bpf_counter_ops;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	struct list_head	bpf_counter_list; /* for perf-stat -b */
15862306a36Sopenharmony_ci	struct list_head	bpf_filters; /* for perf-record --filter */
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	/* for perf-stat --use-bpf */
16162306a36Sopenharmony_ci	int			bperf_leader_prog_fd;
16262306a36Sopenharmony_ci	int			bperf_leader_link_fd;
16362306a36Sopenharmony_ci	union {
16462306a36Sopenharmony_ci		struct bperf_leader_bpf *leader_skel;
16562306a36Sopenharmony_ci		struct bperf_follower_bpf *follower_skel;
16662306a36Sopenharmony_ci		void *bpf_skel;
16762306a36Sopenharmony_ci	};
16862306a36Sopenharmony_ci	unsigned long		open_flags;
16962306a36Sopenharmony_ci	int			precise_ip_original;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/* for missing_features */
17262306a36Sopenharmony_ci	struct perf_pmu		*pmu;
17362306a36Sopenharmony_ci};
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cistruct perf_missing_features {
17662306a36Sopenharmony_ci	bool sample_id_all;
17762306a36Sopenharmony_ci	bool exclude_guest;
17862306a36Sopenharmony_ci	bool mmap2;
17962306a36Sopenharmony_ci	bool cloexec;
18062306a36Sopenharmony_ci	bool clockid;
18162306a36Sopenharmony_ci	bool clockid_wrong;
18262306a36Sopenharmony_ci	bool lbr_flags;
18362306a36Sopenharmony_ci	bool write_backward;
18462306a36Sopenharmony_ci	bool group_read;
18562306a36Sopenharmony_ci	bool ksymbol;
18662306a36Sopenharmony_ci	bool bpf;
18762306a36Sopenharmony_ci	bool aux_output;
18862306a36Sopenharmony_ci	bool branch_hw_idx;
18962306a36Sopenharmony_ci	bool cgroup;
19062306a36Sopenharmony_ci	bool data_page_size;
19162306a36Sopenharmony_ci	bool code_page_size;
19262306a36Sopenharmony_ci	bool weight_struct;
19362306a36Sopenharmony_ci	bool read_lost;
19462306a36Sopenharmony_ci};
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ciextern struct perf_missing_features perf_missing_features;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_cistruct perf_cpu_map;
19962306a36Sopenharmony_cistruct thread_map;
20062306a36Sopenharmony_cistruct record_opts;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistatic inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel)
20362306a36Sopenharmony_ci{
20462306a36Sopenharmony_ci	return perf_evsel__cpus(&evsel->core);
20562306a36Sopenharmony_ci}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_cistatic inline int evsel__nr_cpus(struct evsel *evsel)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	return perf_cpu_map__nr(evsel__cpus(evsel));
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_civoid evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
21362306a36Sopenharmony_ci			   struct perf_counts_values *count);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ciint evsel__object_config(size_t object_size,
21662306a36Sopenharmony_ci			 int (*init)(struct evsel *evsel),
21762306a36Sopenharmony_ci			 void (*fini)(struct evsel *evsel));
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistruct perf_pmu *evsel__find_pmu(const struct evsel *evsel);
22062306a36Sopenharmony_cibool evsel__is_aux_event(const struct evsel *evsel);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistruct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_cistatic inline struct evsel *evsel__new(struct perf_event_attr *attr)
22562306a36Sopenharmony_ci{
22662306a36Sopenharmony_ci	return evsel__new_idx(attr, 0);
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistruct evsel *evsel__clone(struct evsel *orig);
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ciint copy_config_terms(struct list_head *dst, struct list_head *src);
23262306a36Sopenharmony_civoid free_config_terms(struct list_head *config_terms);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
23662306a36Sopenharmony_cistruct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx);
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci/*
23962306a36Sopenharmony_ci * Returns pointer with encoded error via <linux/err.h> interface.
24062306a36Sopenharmony_ci */
24162306a36Sopenharmony_cistatic inline struct evsel *evsel__newtp(const char *sys, const char *name)
24262306a36Sopenharmony_ci{
24362306a36Sopenharmony_ci	return evsel__newtp_idx(sys, name, 0);
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci#endif
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
24862306a36Sopenharmony_cistruct tep_event *event_format__new(const char *sys, const char *name);
24962306a36Sopenharmony_ci#endif
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_civoid evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx);
25262306a36Sopenharmony_civoid evsel__exit(struct evsel *evsel);
25362306a36Sopenharmony_civoid evsel__delete(struct evsel *evsel);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_cistruct callchain_param;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_civoid evsel__config(struct evsel *evsel, struct record_opts *opts,
25862306a36Sopenharmony_ci		   struct callchain_param *callchain);
25962306a36Sopenharmony_civoid evsel__config_callchain(struct evsel *evsel, struct record_opts *opts,
26062306a36Sopenharmony_ci			     struct callchain_param *callchain);
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ciint __evsel__sample_size(u64 sample_type);
26362306a36Sopenharmony_civoid evsel__calc_id_pos(struct evsel *evsel);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_cibool evsel__is_cache_op_valid(u8 type, u8 op);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_cistatic inline bool evsel__is_bpf(struct evsel *evsel)
26862306a36Sopenharmony_ci{
26962306a36Sopenharmony_ci	return evsel->bpf_counter_ops != NULL;
27062306a36Sopenharmony_ci}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cistatic inline bool evsel__is_bperf(struct evsel *evsel)
27362306a36Sopenharmony_ci{
27462306a36Sopenharmony_ci	return evsel->bpf_counter_ops != NULL && list_empty(&evsel->bpf_counter_list);
27562306a36Sopenharmony_ci}
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci#define EVSEL__MAX_ALIASES 8
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ciextern const char *const evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX][EVSEL__MAX_ALIASES];
28062306a36Sopenharmony_ciextern const char *const evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][EVSEL__MAX_ALIASES];
28162306a36Sopenharmony_ciextern const char *const evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX][EVSEL__MAX_ALIASES];
28262306a36Sopenharmony_ciextern const char *const evsel__hw_names[PERF_COUNT_HW_MAX];
28362306a36Sopenharmony_ciextern const char *const evsel__sw_names[PERF_COUNT_SW_MAX];
28462306a36Sopenharmony_ciextern char *evsel__bpf_counter_events;
28562306a36Sopenharmony_cibool evsel__match_bpf_counter_events(const char *name);
28662306a36Sopenharmony_ciint arch_evsel__hw_name(struct evsel *evsel, char *bf, size_t size);
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ciint __evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size);
28962306a36Sopenharmony_ciconst char *evsel__name(struct evsel *evsel);
29062306a36Sopenharmony_cibool evsel__name_is(struct evsel *evsel, const char *name);
29162306a36Sopenharmony_ciconst char *evsel__metric_id(const struct evsel *evsel);
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_cistatic inline bool evsel__is_tool(const struct evsel *evsel)
29462306a36Sopenharmony_ci{
29562306a36Sopenharmony_ci	return evsel->tool_event != PERF_TOOL_NONE;
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ciconst char *evsel__group_name(struct evsel *evsel);
29962306a36Sopenharmony_ciint evsel__group_desc(struct evsel *evsel, char *buf, size_t size);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_civoid __evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit);
30262306a36Sopenharmony_civoid __evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci#define evsel__set_sample_bit(evsel, bit) \
30562306a36Sopenharmony_ci	__evsel__set_sample_bit(evsel, PERF_SAMPLE_##bit)
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci#define evsel__reset_sample_bit(evsel, bit) \
30862306a36Sopenharmony_ci	__evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit)
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_civoid evsel__set_sample_id(struct evsel *evsel, bool use_sample_identifier);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_civoid arch_evsel__set_sample_weight(struct evsel *evsel);
31362306a36Sopenharmony_civoid arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr);
31462306a36Sopenharmony_ciint arch_evsel__open_strerror(struct evsel *evsel, char *msg, size_t size);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ciint evsel__set_filter(struct evsel *evsel, const char *filter);
31762306a36Sopenharmony_ciint evsel__append_tp_filter(struct evsel *evsel, const char *filter);
31862306a36Sopenharmony_ciint evsel__append_addr_filter(struct evsel *evsel, const char *filter);
31962306a36Sopenharmony_ciint evsel__enable_cpu(struct evsel *evsel, int cpu_map_idx);
32062306a36Sopenharmony_ciint evsel__enable(struct evsel *evsel);
32162306a36Sopenharmony_ciint evsel__disable(struct evsel *evsel);
32262306a36Sopenharmony_ciint evsel__disable_cpu(struct evsel *evsel, int cpu_map_idx);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ciint evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu_map_idx);
32562306a36Sopenharmony_ciint evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads);
32662306a36Sopenharmony_ciint evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus,
32762306a36Sopenharmony_ci		struct perf_thread_map *threads);
32862306a36Sopenharmony_civoid evsel__close(struct evsel *evsel);
32962306a36Sopenharmony_ciint evsel__prepare_open(struct evsel *evsel, struct perf_cpu_map *cpus,
33062306a36Sopenharmony_ci		struct perf_thread_map *threads);
33162306a36Sopenharmony_cibool evsel__detect_missing_features(struct evsel *evsel);
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cienum rlimit_action { NO_CHANGE, SET_TO_MAX, INCREASED_MAX };
33462306a36Sopenharmony_cibool evsel__increase_rlimit(enum rlimit_action *set_rlimit);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_cibool evsel__precise_ip_fallback(struct evsel *evsel);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistruct perf_sample;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
34162306a36Sopenharmony_civoid *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name);
34262306a36Sopenharmony_ciu64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name);
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cistatic inline char *evsel__strval(struct evsel *evsel, struct perf_sample *sample, const char *name)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	return evsel__rawptr(evsel, sample, name);
34762306a36Sopenharmony_ci}
34862306a36Sopenharmony_ci#endif
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistruct tep_format_field;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ciu64 format_field__intval(struct tep_format_field *field, struct perf_sample *sample, bool needs_swap);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cistruct tep_format_field *evsel__field(struct evsel *evsel, const char *name);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic inline bool __evsel__match(const struct evsel *evsel, u32 type, u64 config)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	if (evsel->core.attr.type != type)
35962306a36Sopenharmony_ci		return false;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	if ((type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE)  &&
36262306a36Sopenharmony_ci	    perf_pmus__supports_extended_type())
36362306a36Sopenharmony_ci		return (evsel->core.attr.config & PERF_HW_EVENT_MASK) == config;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	return evsel->core.attr.config == config;
36662306a36Sopenharmony_ci}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci#define evsel__match(evsel, t, c) __evsel__match(evsel, PERF_TYPE_##t, PERF_COUNT_##c)
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic inline bool evsel__match2(struct evsel *e1, struct evsel *e2)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	return (e1->core.attr.type == e2->core.attr.type) &&
37362306a36Sopenharmony_ci	       (e1->core.attr.config == e2->core.attr.config);
37462306a36Sopenharmony_ci}
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ciint evsel__read_counter(struct evsel *evsel, int cpu_map_idx, int thread);
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ciint __evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread, bool scale);
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci/**
38162306a36Sopenharmony_ci * evsel__read_on_cpu - Read out the results on a CPU and thread
38262306a36Sopenharmony_ci *
38362306a36Sopenharmony_ci * @evsel - event selector to read value
38462306a36Sopenharmony_ci * @cpu_map_idx - CPU of interest
38562306a36Sopenharmony_ci * @thread - thread of interest
38662306a36Sopenharmony_ci */
38762306a36Sopenharmony_cistatic inline int evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread)
38862306a36Sopenharmony_ci{
38962306a36Sopenharmony_ci	return __evsel__read_on_cpu(evsel, cpu_map_idx, thread, false);
39062306a36Sopenharmony_ci}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci/**
39362306a36Sopenharmony_ci * evsel__read_on_cpu_scaled - Read out the results on a CPU and thread, scaled
39462306a36Sopenharmony_ci *
39562306a36Sopenharmony_ci * @evsel - event selector to read value
39662306a36Sopenharmony_ci * @cpu_map_idx - CPU of interest
39762306a36Sopenharmony_ci * @thread - thread of interest
39862306a36Sopenharmony_ci */
39962306a36Sopenharmony_cistatic inline int evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu_map_idx, int thread)
40062306a36Sopenharmony_ci{
40162306a36Sopenharmony_ci	return __evsel__read_on_cpu(evsel, cpu_map_idx, thread, true);
40262306a36Sopenharmony_ci}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ciint evsel__parse_sample(struct evsel *evsel, union perf_event *event,
40562306a36Sopenharmony_ci			struct perf_sample *sample);
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ciint evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event,
40862306a36Sopenharmony_ci				  u64 *timestamp);
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ciu16 evsel__id_hdr_size(struct evsel *evsel);
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_cistatic inline struct evsel *evsel__next(struct evsel *evsel)
41362306a36Sopenharmony_ci{
41462306a36Sopenharmony_ci	return list_entry(evsel->core.node.next, struct evsel, core.node);
41562306a36Sopenharmony_ci}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistatic inline struct evsel *evsel__prev(struct evsel *evsel)
41862306a36Sopenharmony_ci{
41962306a36Sopenharmony_ci	return list_entry(evsel->core.node.prev, struct evsel, core.node);
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/**
42362306a36Sopenharmony_ci * evsel__is_group_leader - Return whether given evsel is a leader event
42462306a36Sopenharmony_ci *
42562306a36Sopenharmony_ci * @evsel - evsel selector to be tested
42662306a36Sopenharmony_ci *
42762306a36Sopenharmony_ci * Return %true if @evsel is a group leader or a stand-alone event
42862306a36Sopenharmony_ci */
42962306a36Sopenharmony_cistatic inline bool evsel__is_group_leader(const struct evsel *evsel)
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci	return evsel->core.leader == &evsel->core;
43262306a36Sopenharmony_ci}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci/**
43562306a36Sopenharmony_ci * evsel__is_group_event - Return whether given evsel is a group event
43662306a36Sopenharmony_ci *
43762306a36Sopenharmony_ci * @evsel - evsel selector to be tested
43862306a36Sopenharmony_ci *
43962306a36Sopenharmony_ci * Return %true iff event group view is enabled and @evsel is a actual group
44062306a36Sopenharmony_ci * leader which has other members in the group
44162306a36Sopenharmony_ci */
44262306a36Sopenharmony_cistatic inline bool evsel__is_group_event(struct evsel *evsel)
44362306a36Sopenharmony_ci{
44462306a36Sopenharmony_ci	if (!symbol_conf.event_group)
44562306a36Sopenharmony_ci		return false;
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	return evsel__is_group_leader(evsel) && evsel->core.nr_members > 1;
44862306a36Sopenharmony_ci}
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cibool evsel__is_function_event(struct evsel *evsel);
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_cistatic inline bool evsel__is_bpf_output(struct evsel *evsel)
45362306a36Sopenharmony_ci{
45462306a36Sopenharmony_ci	return evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT);
45562306a36Sopenharmony_ci}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cistatic inline bool evsel__is_clock(const struct evsel *evsel)
45862306a36Sopenharmony_ci{
45962306a36Sopenharmony_ci	return evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
46062306a36Sopenharmony_ci	       evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK);
46162306a36Sopenharmony_ci}
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_cibool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize);
46462306a36Sopenharmony_ciint evsel__open_strerror(struct evsel *evsel, struct target *target,
46562306a36Sopenharmony_ci			 int err, char *msg, size_t size);
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_cistatic inline int evsel__group_idx(struct evsel *evsel)
46862306a36Sopenharmony_ci{
46962306a36Sopenharmony_ci	return evsel->core.idx - evsel->core.leader->idx;
47062306a36Sopenharmony_ci}
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci/* Iterates group WITHOUT the leader. */
47362306a36Sopenharmony_ci#define for_each_group_member_head(_evsel, _leader, _head)				\
47462306a36Sopenharmony_cifor ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node);		\
47562306a36Sopenharmony_ci	(_evsel) && &(_evsel)->core.node != (_head) &&					\
47662306a36Sopenharmony_ci	(_evsel)->core.leader == &(_leader)->core;					\
47762306a36Sopenharmony_ci	(_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci#define for_each_group_member(_evsel, _leader)				\
48062306a36Sopenharmony_ci	for_each_group_member_head(_evsel, _leader, &(_leader)->evlist->core.entries)
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci/* Iterates group WITH the leader. */
48362306a36Sopenharmony_ci#define for_each_group_evsel_head(_evsel, _leader, _head)				\
48462306a36Sopenharmony_cifor ((_evsel) = _leader;								\
48562306a36Sopenharmony_ci	(_evsel) && &(_evsel)->core.node != (_head) &&					\
48662306a36Sopenharmony_ci	(_evsel)->core.leader == &(_leader)->core;					\
48762306a36Sopenharmony_ci	(_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci#define for_each_group_evsel(_evsel, _leader)				\
49062306a36Sopenharmony_ci	for_each_group_evsel_head(_evsel, _leader, &(_leader)->evlist->core.entries)
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_cistatic inline bool evsel__has_branch_callstack(const struct evsel *evsel)
49362306a36Sopenharmony_ci{
49462306a36Sopenharmony_ci	return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK;
49562306a36Sopenharmony_ci}
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_cistatic inline bool evsel__has_branch_hw_idx(const struct evsel *evsel)
49862306a36Sopenharmony_ci{
49962306a36Sopenharmony_ci	return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
50062306a36Sopenharmony_ci}
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_cistatic inline bool evsel__has_callchain(const struct evsel *evsel)
50362306a36Sopenharmony_ci{
50462306a36Sopenharmony_ci	/*
50562306a36Sopenharmony_ci	 * For reporting purposes, an evsel sample can have a recorded callchain
50662306a36Sopenharmony_ci	 * or a callchain synthesized from AUX area data.
50762306a36Sopenharmony_ci	 */
50862306a36Sopenharmony_ci	return evsel->core.attr.sample_type & PERF_SAMPLE_CALLCHAIN ||
50962306a36Sopenharmony_ci	       evsel->synth_sample_type & PERF_SAMPLE_CALLCHAIN;
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_cistatic inline bool evsel__has_br_stack(const struct evsel *evsel)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	/*
51562306a36Sopenharmony_ci	 * For reporting purposes, an evsel sample can have a recorded branch
51662306a36Sopenharmony_ci	 * stack or a branch stack synthesized from AUX area data.
51762306a36Sopenharmony_ci	 */
51862306a36Sopenharmony_ci	return evsel->core.attr.sample_type & PERF_SAMPLE_BRANCH_STACK ||
51962306a36Sopenharmony_ci	       evsel->synth_sample_type & PERF_SAMPLE_BRANCH_STACK;
52062306a36Sopenharmony_ci}
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_cistatic inline bool evsel__is_dummy_event(struct evsel *evsel)
52362306a36Sopenharmony_ci{
52462306a36Sopenharmony_ci	return (evsel->core.attr.type == PERF_TYPE_SOFTWARE) &&
52562306a36Sopenharmony_ci	       (evsel->core.attr.config == PERF_COUNT_SW_DUMMY);
52662306a36Sopenharmony_ci}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_cistruct perf_env *evsel__env(struct evsel *evsel);
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ciint evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_civoid evsel__zero_per_pkg(struct evsel *evsel);
53362306a36Sopenharmony_cibool evsel__is_hybrid(const struct evsel *evsel);
53462306a36Sopenharmony_cistruct evsel *evsel__leader(const struct evsel *evsel);
53562306a36Sopenharmony_cibool evsel__has_leader(struct evsel *evsel, struct evsel *leader);
53662306a36Sopenharmony_cibool evsel__is_leader(struct evsel *evsel);
53762306a36Sopenharmony_civoid evsel__set_leader(struct evsel *evsel, struct evsel *leader);
53862306a36Sopenharmony_ciint evsel__source_count(const struct evsel *evsel);
53962306a36Sopenharmony_civoid evsel__remove_from_group(struct evsel *evsel, struct evsel *leader);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_cibool arch_evsel__must_be_in_group(const struct evsel *evsel);
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci/*
54462306a36Sopenharmony_ci * Macro to swap the bit-field postition and size.
54562306a36Sopenharmony_ci * Used when,
54662306a36Sopenharmony_ci * - dont need to swap the entire u64 &&
54762306a36Sopenharmony_ci * - when u64 has variable bit-field sizes &&
54862306a36Sopenharmony_ci * - when presented in a host endian which is different
54962306a36Sopenharmony_ci *   than the source endian of the perf.data file
55062306a36Sopenharmony_ci */
55162306a36Sopenharmony_ci#define bitfield_swap(src, pos, size)	\
55262306a36Sopenharmony_ci	((((src) >> (pos)) & ((1ull << (size)) - 1)) << (63 - ((pos) + (size) - 1)))
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ciu64 evsel__bitfield_swap_branch_flags(u64 value);
55562306a36Sopenharmony_civoid evsel__set_config_if_unset(struct perf_pmu *pmu, struct evsel *evsel,
55662306a36Sopenharmony_ci				const char *config_name, u64 val);
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci#endif /* __PERF_EVSEL_H */
559