1LIBPFM(3) Linux Programmer's Manual LIBPFM(3)
2
3
4
6 pfm_dispatch_events - determine PMC registers values for a set of
7 events to measure
8
10 #include <perfmon/pfmlib.h>
11
12 int pfm_dispatch_events(pfmlib_input_param_t *p, void *mod_in, pfmlib_output_param_t *q,void *mod_out);
13
14
16 This function is the central piece of the library. It is important to
17 understand that the library does not effectively program the PMU, i.e.,
18 it does not make the operating system calls. The PMU is never actually
19 accessed by the library. Instead, the library helps applications pre‐
20 pare the arguments to pass to the kernel. In particular, it sets up the
21 values to program into the PMU configuration registers (PMC). The list
22 of used data registers (PMD) is also returned.
23
24 The input argument are divided into two categories: the generic argu‐
25 ments in p and the optional PMU model specific arguments in mod_in.
26 The same applies for the output arguments: q contains the generic out‐
27 put arguments and mod_out the optional PMU model specific arguments.
28
29 An application describes what it wants to measure in the in and if it
30 uses some model specific features, such as opcode matching on Itanium 2
31 processors, it must pass a pointer to the relevant model-specific input
32 parameters in mod_in. The generic output parameters contains the regis‐
33 ter index and values for the PMC and PMD registers needed to make the
34 measurement. The index mapping is guaranteed to match the mapping used
35 by the Linux perfmon2 interface. In case the library is not used on
36 this system, the hardware register addresses or indexes can also be
37 retrieved from the output structure.
38
39 The pfmlib_input_param_t structure is defined as follows:
40
41 typedef struct
42 int event;
43 unsigned int plm;
44 unsigned long flags;
45 unsigned int unit_masks[PFMLIB_MAX_MASKS_PER_EVENT];
46 unsigned int num_masks;
47 } pfmlib_event_t;
48
49 typedef struct {
50 unsigned int pfp_event_count;
51 unsigned int pfp_dfl_plm;
52 unsigned int pfp_flags;
53 pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS];
54 pfmlib_regmask_t pfp_unavail_pmcs;
55 } pfmlib_input_param_t;
56
57 The structure mostly contains one table, called pfp_events which
58 describes the events to be measured. The number of submitted events is
59 indicated by pfp_event_count.
60
61 Each event is described in the pfp_events table by an opaque descriptor
62 stored in the event field. This descriptor is obtained with the
63 pfm_find_full_event() or derivative functions. For some events, it may
64 be necessary to specify at least one unit mask in the unit_masks table.
65 A unit mask is yet another opaque descriptor obtained via the
66 pfm_find_event_mask() or pfm_find_full_event() functions. Typically, if
67 an event supports multiple unit masks, they can be combined in which
68 case more than one entry in unit_masks must be specified. The actual
69 number of unit mask descriptors passed must be indicated in num_masks.
70 When no unit mask is used, this field must be set to 0.
71
72 A privilege level mask for the event can be provided in plm. This is a
73 bitmask where each bit indicates a privilege level at which to monitor,
74 more than one bit can be set. The library supports up to four levels,
75 but depending on the PMU model, some levels may not be available. The
76 levels are as follows:
77
78 PFM_PLM0
79 monitor at the privilege level 0. For many architectures, this
80 means kernel level
81
82 PFM_PLM1
83 monitor at privilege level 1
84
85 PFM_PLM2
86 monitor at privilege level 2
87
88 PFM_PLM3
89 monitor at the privilege level 3. For many architectures, this
90 means user level
91
92 Events with a plm value of 0 will use the default privilege level mask
93 as indicated by pfp_dfl_plm which must be set to any combinations of
94 values described above. It is illegal to have a value of 0 for this
95 field.
96
97 The pfp_flags field contains a set of flags that affect the whole set
98 of events to be monitored. The currently defined flags are:
99
100 PFMLIB_PFP_SYSTEMWIDE
101 indicates that the monitors are to be used in a system-wide mon‐
102 itoring session. This could influence the way the library sets
103 up some register values.
104
105
106 The pfp_unavail_pmcs bitmask can be used by applications to communicate
107 to the library the list of PMC registers which are not available on the
108 system. Some kernels may allocate certain PMC registers (and associ‐
109 ated data registers) for other purposes. Those registers must not be
110 used by the library otherwise the assignment of events to PMC registers
111 may be rejected by the kernel. Applications must figure out which reg‐
112 isters are available using a kernel interface at their disposal, the
113 library does not provide this service. The library expect the restric‐
114 tions to be expressed using the Linux perfmon2 PMC register mapping.
115
116 Refer to the PMU specific manual for a description of the model-spe‐
117 cific input parameters to be passed in mod_in.
118
119 The generic output parameters are contained in the fBpfmlib_out‐
120 put_param_t structure which is defined as:
121
122 typedef struct {
123 unsigned long long reg_value;
124 unsigned int reg_num;
125 unsigned long reg_addr;
126 } pfmlib_reg_t;
127
128 typedef struct {
129 unsigned int pfp_pmc_count;
130 unsigned int pfp_pmd_count;
131 pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS];
132 pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS];
133 } pfmlib_output_param_t;
134
135 The number of valid entries in the pfp_pmcs table is indicated by
136 pfp_pmc_count. The number of valid entries in the pfp_pmds table is
137 indicated by pfp_pmd_count. Each entry in both tables is of type pfm‐
138 lib_reg_t.
139
140 In the pfp_pmcs table, the reg_num contains the PMC register index
141 (perfmon2 mapping), and the reg_value contains a 64-bit value to be
142 used to program the PMC register. The reg_addr indicates the hardware
143 address or index for the PMC register.
144
145 In the pfp_pmds table, the reg_num contains the PMD register index
146 (perfmon2 mapping). the reg_value is ignored. The reg_addr indicates
147 the hardware address or index for the PMC register.
148
149 Refer to the PMU specific manual for a description of the model-spe‐
150 cific output parameters to be returned in mod_out.
151
152 The current implementation of the pfm_dispatch_events() function com‐
153 pletely overwrites the pfmlib_output_param structure. In other words,
154 results do not accumulate into the pfp_pmcs table across multiple
155 calls. Unused fields are guaranteed to be zeroed upon successful
156 return.
157
158 Depending on the PMU model, there may not always be a one to one map‐
159 ping between a PMC register and a data register. Register dependencies
160 may be more intricate. However the pfm_dispatch_events() function
161 guarantees certain ordering between the pfp_pmcs and pfp_pmds tables.
162 In particular, it guarantees that the pfp_pmds table always starts with
163 the counters corresponding, in the same order, to the events as pro‐
164 vided in the pfp_event table on input. There is always one counter per
165 event. Additional PMD registers, if any, come after.
166
168 Here is a typical sequence using the perfmon2 interface:
169 #include <perfmon/pfmlib.h>
170 ...
171 pfmlib_input_param_t inp;
172 pfmlib_output_param_t outp;
173 pfarg_ctx_t ctx;
174 pfarg_pmd_t pd[1];
175 pfarg_pmc_t pc[1];
176 pfarg_load_t load_arg;
177 int fd, i;
178 int ret;
179
180 if (pfm_initialize() != PFMLIB_SUCCESS) {
181 fprintf(stderr, "can't initialize library\n");
182 exit(1);
183 }
184 memset(&ctx,0, sizeof(ctx));
185 memset(&inp,0, sizeof(inp));
186 memset(&outp,0, sizeof(outp));
187 memset(pd, 0, sizeof(pd));
188 memset(pc, 0, sizeof(pc));
189 memset(&load_arg, 0, sizeof(load_arg));
190
191 ret = pfm_get_cycle_event(&inp.pfp_events[0]);
192 if (ret != PFMLIB_SUCCESS) {
193 fprintf(stderr, "cannot find cycle event\n");
194 exit(1);
195 }
196 inp.pfp_dfl_plm = PFM_PLM3;
197 inp.pfp_event_count = 1;
198
199 ret = pfm_dispatch_events(&inp, NULL, &outp, NULL);
200 if (ret != PFMLIB_SUCCESS) {
201 fprintf(stderr, "cannot dispatch events: %s\n", pfm_strerror(ret));
202 exit(1);
203 }
204 /* propagate pmc value to perfmon2 structures */
205 for(i=0; i < outp.pfp_pmc_count; i++) {
206 pc[i].reg_num = outp.pfp_pmcs[i].reg_num;
207 pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
208 }
209 for(i=0; i < outp.pfp_pmd_count; i++) {
210 pd[i].reg_num = outp.pfp_pmds[i].reg_num;
211 pd[i].reg_value = 0;
212 }
213 ...
214 if (pfm_create_context(&ctx, NULL, 0) == -1 ) {
215 ...
216 }
217 fd = ctx.ctx_fd;
218
219 if (pfm_write_pmcs(fd, pc, outp.pfp_pmc_count) == -1) {
220 ...
221 }
222 if (pfm_write_pmds(fd, pd, outp.pfp_pmd_count) == -1) {
223 ...
224 }
225
226 load_arg.load_pid = getpid();
227 if (pfm_load_context(fd, &load_arg) == -1) {
228 ...
229 }
230
231 pfm_start(fd, NULL);
232 /* code to monitor */
233 pfm_stop(fd);
234
235 if (pfm_read_pmds(fd, pd, evt.pfp_event_count) == -1) {
236 ...
237 }
238 printf("results: %llu0, pd[0].reg_value);
239 ...
240 close(fd);
241 ...
242
243
245 The function returns whether or not the call was successful. A return
246 value of PFMLIB_SUCCESS indicates success, otherwise the value is the
247 error code.
248
250 PFMLIB_ERR_NOINIT The library has not been initialized properly.
251
252 PFMLIB_ERR_INVAL
253 Some arguments were invalid. For instance the value of *count is
254 zero. This can also be due to he content of the pfmlib_param_t
255 structure.
256
257 PFMLIB_ERR_NOTFOUND
258 No matching event was found.
259
260 PFMLIB_ERR_TOOMANY
261 The number of events to monitor exceed the number of implemented
262 counters.
263
264 PFMLIB_ERR_NOASSIGN
265 The events cannot be dispatched to the PMC because events have
266 conflicting constraints.
267
268 PFMLIB_ERR_MAGIC
269 The model specific extension does not have the right magic num‐
270 ber.
271
272 PFMLIB_ERR_FEATCOMB
273 The set of events and features cannot be combined.
274
275 PFMLIB_ERR_EVTMANY
276 An event has been supplied more than once and is causing
277 resource (PMC) conflicts.
278
279 PFMLIB_ERR_IRRINVAL
280 Invalid code range restriction (Itanium, Itanium 2).
281
282 PFMLIB_ERR_IRRALIGN
283 Code range has invalid alignment (Itanium, Itanium 2).
284
285 PFMLIB_ERR_IRRTOOMANY
286 Cannot satisfy all the code ranges (Itanium, Itanium 2).
287
288 PFMLIB_ERR_DRRTOOMANY
289 Cannot satisfy all the data ranges (Itanium, Itanium 2).
290
291 PFMLIB_ERR_DRRINVAL
292 Invalid data range restriction (Itanium, Itanium 2).
293
294 PFMLIB_ERR_EVTSET
295 Some events belong to incompatible sets (Itanium 2).
296
297 PFMLIB_ERR_EVTINCOMP
298 Some events cannot be measured at the same time (Itanium 2).
299
300 PFMLIB_ERR_IRRTOOBIG
301 Code range is too big (Itanium 2).
302
303 PFMLIB_ERR_UMASK
304 Invalid or missing unit mask.
305
307 libpfm_itanium(3), libpfm_itanium2(3), pfm_regmask_set(3), pfm_reg‐
308 mask_clr(3), pfm_find_event_code_mask(3)
309
311 Stephane Eranian <eranian@hpl.hp.com>
312
313 July , 2003 LIBPFM(3)