summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/cpumap.h
blob: 26cf76c693f5ea3e6861f727126f731f92e33525 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PERF_CPUMAP_H
#define __PERF_CPUMAP_H

#include <stdbool.h>
#include <stdio.h>
#include <perf/cpumap.h>
#include <linux/refcount.h>

/** Identify where counts are aggregated, -1 implies not to aggregate. */
struct aggr_cpu_id {
	/** A value in the range 0 to number of threads. */
	int thread_idx;
	/** The numa node X as read from /sys/devices/system/node/nodeX. */
	int node;
	/**
	 * The socket number as read from
	 * /sys/devices/system/cpu/cpuX/topology/physical_package_id.
	 */
	int socket;
	/** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
	int die;
	/** The cluster id as read from /sys/devices/system/cpu/cpuX/topology/cluster_id */
	int cluster;
	/** The cache level as read from /sys/devices/system/cpu/cpuX/cache/indexY/level */
	int cache_lvl;
	/**
	 * The cache instance ID, which is the first CPU in the
	 * /sys/devices/system/cpu/cpuX/cache/indexY/shared_cpu_list
	 */
	int cache;
	/** The core id as read from /sys/devices/system/cpu/cpuX/topology/core_id. */
	int core;
	/** CPU aggregation, note there is one CPU for each SMT thread. */
	struct perf_cpu cpu;
};

/** A collection of aggr_cpu_id values, the "built" version is sorted and uniqued. */
struct cpu_aggr_map {
	refcount_t refcnt;
	/** Number of valid entries. */
	int nr;
	/** The entries. */
	struct aggr_cpu_id map[];
};

#define cpu_aggr_map__for_each_idx(idx, aggr_map)				\
	for ((idx) = 0; (idx) < aggr_map->nr; (idx)++)

struct perf_record_cpu_map_data;

bool perf_record_cpu_map_data__test_bit(int i, const struct perf_record_cpu_map_data *data);

struct perf_cpu_map *perf_cpu_map__empty_new(int nr);

struct perf_cpu_map *cpu_map__new_data(const struct perf_record_cpu_map_data *data);
size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */

int cpu__setup_cpunode_map(void);

int cpu__max_node(void);
struct perf_cpu cpu__max_cpu(void);
struct perf_cpu cpu__max_present_cpu(void);

/**
 * cpu_map__is_dummy - Events associated with a pid, rather than a CPU, use a single dummy map with an entry of -1.
 */
static inline bool cpu_map__is_dummy(const struct perf_cpu_map *cpus)
{
	return perf_cpu_map__nr(cpus) == 1 && perf_cpu_map__cpu(cpus, 0).cpu == -1;
}

/**
 * cpu__get_node - Returns the numa node X as read from
 * /sys/devices/system/node/nodeX for the given CPU.
 */
int cpu__get_node(struct perf_cpu cpu);
/**
 * cpu__get_socket_id - Returns the socket number as read from
 * /sys/devices/system/cpu/cpuX/topology/physical_package_id for the given CPU.
 */
int cpu__get_socket_id(struct perf_cpu cpu);
/**
 * cpu__get_die_id - Returns the die id as read from
 * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
 */
int cpu__get_die_id(struct perf_cpu cpu);
/**
 * cpu__get_cluster_id - Returns the cluster id as read from
 * /sys/devices/system/cpu/cpuX/topology/cluster_id for the given CPU
 */
int cpu__get_cluster_id(struct perf_cpu cpu);
/**
 * cpu__get_core_id - Returns the core id as read from
 * /sys/devices/system/cpu/cpuX/topology/core_id for the given CPU.
 */
int cpu__get_core_id(struct perf_cpu cpu);

/**
 * cpu_aggr_map__empty_new - Create a cpu_aggr_map of size nr with every entry
 * being empty.
 */
struct cpu_aggr_map *cpu_aggr_map__empty_new(int nr);

typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(struct perf_cpu cpu, void *data);

/**
 * cpu_aggr_map__new - Create a cpu_aggr_map with an aggr_cpu_id for each cpu in
 * cpus. The aggr_cpu_id is created with 'get_id' that may have a data value
 * passed to it. The cpu_aggr_map is sorted with duplicate values removed.
 */
struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
				       aggr_cpu_id_get_t get_id,
				       void *data, bool needs_sort);

bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b);
bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a);
struct aggr_cpu_id aggr_cpu_id__empty(void);


/**
 * aggr_cpu_id__socket - Create an aggr_cpu_id with the socket populated with
 * the socket for cpu. The function signature is compatible with
 * aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu cpu, void *data);
/**
 * aggr_cpu_id__die - Create an aggr_cpu_id with the die and socket populated
 * with the die and socket for cpu. The function signature is compatible with
 * aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data);
/**
 * aggr_cpu_id__cluster - Create an aggr_cpu_id with cluster, die and socket
 * populated with the cluster, die and socket for cpu. The function signature
 * is compatible with aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__cluster(struct perf_cpu cpu, void *data);
/**
 * aggr_cpu_id__core - Create an aggr_cpu_id with the core, cluster, die and
 * socket populated with the core, die and socket for cpu. The function
 * signature is compatible with aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__core(struct perf_cpu cpu, void *data);
/**
 * aggr_cpu_id__core - Create an aggr_cpu_id with the cpu, core, die and socket
 * populated with the cpu, core, die and socket for cpu. The function signature
 * is compatible with aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__cpu(struct perf_cpu cpu, void *data);
/**
 * aggr_cpu_id__node - Create an aggr_cpu_id with the numa node populated for
 * cpu. The function signature is compatible with aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data);
/**
 * aggr_cpu_id__global - Create an aggr_cpu_id for global aggregation.
 * The function signature is compatible with aggr_cpu_id_get_t.
 */
struct aggr_cpu_id aggr_cpu_id__global(struct perf_cpu cpu, void *data);
#endif /* __PERF_CPUMAP_H */