162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __LIBPERF_INTERNAL_EVSEL_H
362306a36Sopenharmony_ci#define __LIBPERF_INTERNAL_EVSEL_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/types.h>
662306a36Sopenharmony_ci#include <linux/perf_event.h>
762306a36Sopenharmony_ci#include <stdbool.h>
862306a36Sopenharmony_ci#include <sys/types.h>
962306a36Sopenharmony_ci#include <internal/cpumap.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct perf_thread_map;
1262306a36Sopenharmony_cistruct xyarray;
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are
1662306a36Sopenharmony_ci * more than one entry in the evlist.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_cistruct perf_sample_id {
1962306a36Sopenharmony_ci	struct hlist_node	 node;
2062306a36Sopenharmony_ci	u64			 id;
2162306a36Sopenharmony_ci	struct perf_evsel	*evsel;
2262306a36Sopenharmony_ci       /*
2362306a36Sopenharmony_ci	* 'idx' will be used for AUX area sampling. A sample will have AUX area
2462306a36Sopenharmony_ci	* data that will be queued for decoding, where there are separate
2562306a36Sopenharmony_ci	* queues for each CPU (per-cpu tracing) or task (per-thread tracing).
2662306a36Sopenharmony_ci	* The sample ID can be used to lookup 'idx' which is effectively the
2762306a36Sopenharmony_ci	* queue number.
2862306a36Sopenharmony_ci	*/
2962306a36Sopenharmony_ci	int			 idx;
3062306a36Sopenharmony_ci	struct perf_cpu		 cpu;
3162306a36Sopenharmony_ci	pid_t			 tid;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	/* Guest machine pid and VCPU, valid only if machine_pid is non-zero */
3462306a36Sopenharmony_ci	pid_t			 machine_pid;
3562306a36Sopenharmony_ci	struct perf_cpu		 vcpu;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	/* Holds total ID period value for PERF_SAMPLE_READ processing. */
3862306a36Sopenharmony_ci	u64			 period;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistruct perf_evsel {
4262306a36Sopenharmony_ci	struct list_head	 node;
4362306a36Sopenharmony_ci	struct perf_event_attr	 attr;
4462306a36Sopenharmony_ci	/** The commonly used cpu map of CPUs the event should be opened upon, etc. */
4562306a36Sopenharmony_ci	struct perf_cpu_map	*cpus;
4662306a36Sopenharmony_ci	/**
4762306a36Sopenharmony_ci	 * The cpu map read from the PMU. For core PMUs this is the list of all
4862306a36Sopenharmony_ci	 * CPUs the event can be opened upon. For other PMUs this is the default
4962306a36Sopenharmony_ci	 * cpu map for opening the event on, for example, the first CPU on a
5062306a36Sopenharmony_ci	 * socket for an uncore event.
5162306a36Sopenharmony_ci	 */
5262306a36Sopenharmony_ci	struct perf_cpu_map	*own_cpus;
5362306a36Sopenharmony_ci	struct perf_thread_map	*threads;
5462306a36Sopenharmony_ci	struct xyarray		*fd;
5562306a36Sopenharmony_ci	struct xyarray		*mmap;
5662306a36Sopenharmony_ci	struct xyarray		*sample_id;
5762306a36Sopenharmony_ci	u64			*id;
5862306a36Sopenharmony_ci	u32			 ids;
5962306a36Sopenharmony_ci	struct perf_evsel	*leader;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	/* parse modifier helper */
6262306a36Sopenharmony_ci	int			 nr_members;
6362306a36Sopenharmony_ci	/*
6462306a36Sopenharmony_ci	 * system_wide is for events that need to be on every CPU, irrespective
6562306a36Sopenharmony_ci	 * of user requested CPUs or threads. Tha main example of this is the
6662306a36Sopenharmony_ci	 * dummy event. Map propagation will set cpus for this event to all CPUs
6762306a36Sopenharmony_ci	 * as software PMU events like dummy, have a CPU map that is empty.
6862306a36Sopenharmony_ci	 */
6962306a36Sopenharmony_ci	bool			 system_wide;
7062306a36Sopenharmony_ci	/*
7162306a36Sopenharmony_ci	 * Some events, for example uncore events, require a CPU.
7262306a36Sopenharmony_ci	 * i.e. it cannot be the 'any CPU' value of -1.
7362306a36Sopenharmony_ci	 */
7462306a36Sopenharmony_ci	bool			 requires_cpu;
7562306a36Sopenharmony_ci	/** Is the PMU for the event a core one? Effects the handling of own_cpus. */
7662306a36Sopenharmony_ci	bool			 is_pmu_core;
7762306a36Sopenharmony_ci	int			 idx;
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_civoid perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr,
8162306a36Sopenharmony_ci		      int idx);
8262306a36Sopenharmony_ciint perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
8362306a36Sopenharmony_civoid perf_evsel__close_fd(struct perf_evsel *evsel);
8462306a36Sopenharmony_civoid perf_evsel__free_fd(struct perf_evsel *evsel);
8562306a36Sopenharmony_ciint perf_evsel__read_size(struct perf_evsel *evsel);
8662306a36Sopenharmony_ciint perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciint perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
8962306a36Sopenharmony_civoid perf_evsel__free_id(struct perf_evsel *evsel);
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#endif /* __LIBPERF_INTERNAL_EVSEL_H */
92