#ifndef __PERF_EVSEL_H
#define __PERF_EVSEL_H 1
#include <linux/list.h>
#include <stdbool.h>
#include <sys/types.h>
#include <linux/perf_event.h>
#include <linux/types.h>
#include <internal/evsel.h>
#include <perf/evsel.h>
#include "symbol_conf.h"
#include "pmus.h"
#include "pmu.h"
struct bpf_object;
struct cgroup;
struct perf_counts;
struct perf_stat_config;
struct perf_stat_evsel;
union perf_event;
struct bpf_counter_ops;
struct target;
struct hashmap;
struct bperf_leader_bpf;
struct bperf_follower_bpf;
typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
struct evsel {
struct perf_evsel core;
struct evlist *evlist;
off_t id_offset;
int id_pos;
int is_pos;
unsigned int sample_size;
struct {
char *name;
char *group_name;
const char *group_pmu_name;
#ifdef HAVE_LIBTRACEEVENT
char *tp_sys;
char *tp_name;
struct tep_event *tp_format;
#endif
char *filter;
unsigned long max_events;
double scale;
const char *unit;
struct cgroup *cgrp;
const char *metric_id;
struct evsel *first_wildcard_match;
int exclude_GH;
int sample_read;
bool snapshot;
bool per_pkg;
bool percore;
bool precise_max;
bool is_libpfm_event;
bool collect_stat;
bool weak_group;
bool bpf_counter;
bool use_config_name;
bool skippable;
bool retire_lat;
bool dont_regroup;
int bpf_fd;
struct bpf_object *bpf_obj;
struct list_head config_terms;
u64 alternate_hw_config;
};
struct evsel *metric_leader;
void *handler;
struct perf_counts *counts;
struct perf_counts *prev_raw_counts;
unsigned long nr_events_printed;
struct perf_stat_evsel *stats;
void *priv;
u64 db_id;
bool uniquified_name;
bool supported;
bool needs_swap;
bool disabled;
bool no_aux_samples;
bool immediate;
bool tracking;
bool ignore_missing_thread;
bool forced_leader;
bool cmdline_group_boundary;
bool reset_group;
bool needs_auxtrace_mmap;
bool default_metricgroup;
bool default_show_events;
bool needs_uniquify;
struct hashmap *per_pkg_mask;
int err;
int script_output_type;
struct {
evsel__sb_cb_t *cb;
void *data;
} side_band;
__u64 synth_sample_type;
int br_cntr_idx;
int br_cntr_nr;
char abbr_name[3];
struct bpf_counter_ops *bpf_counter_ops;
struct list_head bpf_counter_list;
struct list_head bpf_filters;
int bperf_leader_prog_fd;
int bperf_leader_link_fd;
union {
struct bperf_leader_bpf *leader_skel;
struct bperf_follower_bpf *follower_skel;
void *bpf_skel;
};
unsigned long open_flags;
int precise_ip_original;
struct perf_pmu *pmu;
union {
struct _retirement_latency {
double mean;
double min;
double max;
} retirement_latency;
__u64 start_time;
struct xyarray *start_times;
};
bool pid_stat;
};
struct perf_missing_features {
bool sample_id_all;
bool exclude_guest;
bool mmap2;
bool cloexec;
bool clockid;
bool clockid_wrong;
bool lbr_flags;
bool write_backward;
bool group_read;
bool ksymbol;
bool bpf;
bool aux_output;
bool branch_hw_idx;
bool cgroup;
bool data_page_size;
bool code_page_size;
bool weight_struct;
bool read_lost;
bool branch_counters;
bool aux_action;
bool inherit_sample_read;
bool defer_callchain;
};
extern struct perf_missing_features perf_missing_features;
struct perf_cpu_map;
struct thread_map;
struct record_opts;
static inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel)
{
return perf_evsel__cpus(&evsel->core);
}
static inline int evsel__nr_cpus(struct evsel *evsel)
{
return perf_cpu_map__nr(evsel__cpus(evsel));
}
void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
struct perf_counts_values *count);
int evsel__object_config(size_t object_size,
int (*init)(struct evsel *evsel),
void (*fini)(struct evsel *evsel));
struct perf_pmu *evsel__find_pmu(const struct evsel *evsel);
const char *evsel__pmu_name(const struct evsel *evsel);
bool evsel__is_aux_event(const struct evsel *evsel);
struct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx);
static inline struct evsel *evsel__new(struct perf_event_attr *attr)
{
return evsel__new_idx(attr, 0);
}
struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig);
int copy_config_terms(struct list_head *dst, struct list_head *src);
void free_config_terms(struct list_head *config_terms);
struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx, bool format);
static inline struct evsel *evsel__newtp(const char *sys, const char *name)
{
return evsel__newtp_idx(sys, name, 0, true);
}
#ifdef HAVE_LIBTRACEEVENT
struct tep_event *evsel__tp_format(struct evsel *evsel);
#endif
void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx);
void evsel__exit(struct evsel *evsel);
void evsel__delete(struct evsel *evsel);
void evsel__set_priv_destructor(void (*destructor)(void *priv));
struct callchain_param;
void evsel__config(struct evsel *evsel, struct record_opts *opts,
struct callchain_param *callchain);
void evsel__config_callchain(struct evsel *evsel, struct record_opts *opts,
struct callchain_param *callchain);
int __evsel__sample_size(u64 sample_type);
void evsel__calc_id_pos(struct evsel *evsel);
bool evsel__is_cache_op_valid(u8 type, u8 op);
static inline bool evsel__is_bpf(struct evsel *evsel)
{
return evsel->bpf_counter_ops != NULL;
}
static inline bool evsel__is_bperf(struct evsel *evsel)
{
return evsel->bpf_counter_ops != NULL && list_empty(&evsel->bpf_counter_list);
}
#define EVSEL__MAX_ALIASES 8
extern const char *const evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX][EVSEL__MAX_ALIASES];
extern const char *const evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][EVSEL__MAX_ALIASES];
extern const char *const evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX][EVSEL__MAX_ALIASES];
extern const char *const evsel__hw_names[PERF_COUNT_HW_MAX];
extern const char *const evsel__sw_names[PERF_COUNT_SW_MAX];
extern char *evsel__bpf_counter_events;
bool evsel__match_bpf_counter_events(const char *name);
int arch_evsel__hw_name(struct evsel *evsel, char *bf, size_t size);
int __evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size);
const char *evsel__name(struct evsel *evsel);
bool evsel__name_is(struct evsel *evsel, const char *name);
const char *evsel__metric_id(const struct evsel *evsel);
static inline bool evsel__is_retire_lat(const struct evsel *evsel)
{
return evsel->retire_lat;
}
const char *evsel__group_name(struct evsel *evsel);
int evsel__group_desc(struct evsel *evsel, char *buf, size_t size);
void __evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit);
void __evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit);
#define evsel__set_sample_bit(evsel, bit) \
__evsel__set_sample_bit(evsel, PERF_SAMPLE_##bit)
#define evsel__reset_sample_bit(evsel, bit) \
__evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit)
void evsel__set_sample_id(struct evsel *evsel, bool use_sample_identifier);
void arch_evsel__set_sample_weight(struct evsel *evsel);
void arch__post_evsel_config(struct evsel *evsel, struct perf_event_attr *attr);
int arch_evsel__open_strerror(struct evsel *evsel, int err, char *msg, size_t size);
void arch_evsel__apply_ratio_to_prev(struct evsel *evsel, struct perf_event_attr *attr);
int evsel__set_filter(struct evsel *evsel, const char *filter);
int evsel__append_tp_filter(struct evsel *evsel, const char *filter);
int evsel__append_addr_filter(struct evsel *evsel, const char *filter);
int evsel__enable_cpu(struct evsel *evsel, int cpu_map_idx);
int evsel__enable(struct evsel *evsel);
int evsel__disable(struct evsel *evsel);
int evsel__disable_cpu(struct evsel *evsel, int cpu_map_idx);
int evsel__open_per_cpu_and_thread(struct evsel *evsel,
struct perf_cpu_map *cpus, int cpu_map_idx,
struct perf_thread_map *threads);
int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu_map_idx);
int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads);
int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus,
struct perf_thread_map *threads);
void evsel__close(struct evsel *evsel);
int evsel__prepare_open(struct evsel *evsel, struct perf_cpu_map *cpus,
struct perf_thread_map *threads);
bool evsel__precise_ip_fallback(struct evsel *evsel);
struct perf_sample;
#ifdef HAVE_LIBTRACEEVENT
void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name);
u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name);
u64 evsel__intval_common(struct evsel *evsel, struct perf_sample *sample, const char *name);
char evsel__taskstate(struct evsel *evsel, struct perf_sample *sample, const char *name);
static inline char *evsel__strval(struct evsel *evsel, struct perf_sample *sample, const char *name)
{
return evsel__rawptr(evsel, sample, name);
}
#endif
struct tep_format_field;
u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sample, bool needs_swap);
struct tep_format_field *evsel__field(struct evsel *evsel, const char *name);
struct tep_format_field *evsel__common_field(struct evsel *evsel, const char *name);
bool __evsel__match(const struct evsel *evsel, u32 type, u64 config);
#define evsel__match(evsel, t, c) __evsel__match(evsel, PERF_TYPE_##t, PERF_COUNT_##c)
int evsel__read_counter(struct evsel *evsel, int cpu_map_idx, int thread);
int __evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread, bool scale);
static inline int evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread)
{
return __evsel__read_on_cpu(evsel, cpu_map_idx, thread, false);
}
static inline int evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu_map_idx, int thread)
{
return __evsel__read_on_cpu(evsel, cpu_map_idx, thread, true);
}
int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
struct perf_sample *sample);
int evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event,
u64 *timestamp);
u16 evsel__id_hdr_size(const struct evsel *evsel);
static inline struct evsel *evsel__next(struct evsel *evsel)
{
return list_entry(evsel->core.node.next, struct evsel, core.node);
}
static inline struct evsel *evsel__prev(struct evsel *evsel)
{
return list_entry(evsel->core.node.prev, struct evsel, core.node);
}
static inline bool evsel__is_group_leader(const struct evsel *evsel)
{
return evsel->core.leader == &evsel->core;
}
static inline bool evsel__is_group_event(struct evsel *evsel)
{
if (!symbol_conf.event_group)
return false;
return evsel__is_group_leader(evsel) && evsel->core.nr_members > 1;
}
bool evsel__is_function_event(struct evsel *evsel);
static inline bool evsel__is_bpf_output(struct evsel *evsel)
{
return evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT);
}
static inline bool evsel__is_clock(const struct evsel *evsel)
{
return evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK);
}
bool evsel__fallback(struct evsel *evsel, struct target *target, int err,
char *msg, size_t msgsize);
int evsel__open_strerror(struct evsel *evsel, struct target *target,
int err, char *msg, size_t size);
static inline int evsel__group_idx(struct evsel *evsel)
{
return evsel->core.idx - evsel->core.leader->idx;
}
#define for_each_group_member_head(_evsel, _leader, _head) \
for ((_evsel) = list_entry((_leader)->core.node.next, struct evsel, core.node); \
(_evsel) && &(_evsel)->core.node != (_head) && \
(_evsel)->core.leader == &(_leader)->core; \
(_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
#define for_each_group_member(_evsel, _leader) \
for_each_group_member_head(_evsel, _leader, &(_leader)->evlist->core.entries)
#define for_each_group_evsel_head(_evsel, _leader, _head) \
for ((_evsel) = _leader; \
(_evsel) && &(_evsel)->core.node != (_head) && \
(_evsel)->core.leader == &(_leader)->core; \
(_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
#define for_each_group_evsel(_evsel, _leader) \
for_each_group_evsel_head(_evsel, _leader, &(_leader)->evlist->core.entries)
static inline bool evsel__has_branch_callstack(const struct evsel *evsel)
{
return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK;
}
static inline bool evsel__has_branch_hw_idx(const struct evsel *evsel)
{
return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
}
static inline bool evsel__has_callchain(const struct evsel *evsel)
{
return evsel->core.attr.sample_type & PERF_SAMPLE_CALLCHAIN ||
evsel->synth_sample_type & PERF_SAMPLE_CALLCHAIN;
}
static inline bool evsel__has_br_stack(const struct evsel *evsel)
{
return evsel->core.attr.sample_type & PERF_SAMPLE_BRANCH_STACK ||
evsel->synth_sample_type & PERF_SAMPLE_BRANCH_STACK;
}
static inline bool evsel__is_dummy_event(struct evsel *evsel)
{
return (evsel->core.attr.type == PERF_TYPE_SOFTWARE) &&
(evsel->core.attr.config == PERF_COUNT_SW_DUMMY);
}
struct perf_session *evsel__session(struct evsel *evsel);
struct perf_env *evsel__env(struct evsel *evsel);
uint16_t evsel__e_machine(struct evsel *evsel, uint32_t *e_flags);
int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
void evsel__zero_per_pkg(struct evsel *evsel);
bool evsel__is_hybrid(const struct evsel *evsel);
struct evsel *evsel__leader(const struct evsel *evsel);
bool evsel__has_leader(struct evsel *evsel, struct evsel *leader);
bool evsel__is_leader(struct evsel *evsel);
void evsel__set_leader(struct evsel *evsel, struct evsel *leader);
int evsel__source_count(const struct evsel *evsel);
void evsel__remove_from_group(struct evsel *evsel, struct evsel *leader);
bool arch_evsel__must_be_in_group(const struct evsel *evsel);
bool evsel__set_needs_uniquify(struct evsel *counter, const struct perf_stat_config *config);
void evsel__uniquify_counter(struct evsel *counter);
#define bitfield_swap(src, pos, size) \
((((src) >> (pos)) & ((1ull << (size)) - 1)) << (63 - ((pos) + (size) - 1)))
u64 evsel__bitfield_swap_branch_flags(u64 value);
int evsel__get_config_val(const struct evsel *evsel, const char *config_name,
u64 *val);
void evsel__set_config_if_unset(struct evsel *evsel, const char *config_name,
u64 val);
bool evsel__is_offcpu_event(struct evsel *evsel);
void evsel__warn_user_requested_cpus(struct evsel *evsel, struct perf_cpu_map *user_requested_cpus);
#endif