PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
perf_event_uncore.c
Go to the documentation of this file.
1 /*
2 * File: perf_event_uncore.c
3 *
4 * Author: Vince Weaver
5 * vincent.weaver@maine.edu
6 * Mods: Gary Mohr
7 * gary.mohr@bull.com
8 * Modified the perf_event_uncore component to use PFM_OS_PERF_EVENT_EXT mode in libpfm4.
9 * This adds several new event masks, including cpu=, u=, and k= which give the user
10 * the ability to set cpu number to use or control the domain (user, kernel, or both)
11 * in which the counter should be incremented. These are event masks so it is now
12 * possible to have multiple events in the same event set that count activity from
13 * differennt cpu's or count activity in different domains.
14 */
15 
16 #include <fcntl.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include <syscall.h>
21 #include <sys/utsname.h>
22 #include <sys/mman.h>
23 #include <sys/ioctl.h>
24 
25 /* PAPI-specific includes */
26 #include "papi.h"
27 #include "papi_memory.h"
28 #include "papi_internal.h"
29 #include "papi_vector.h"
30 #include "extras.h"
31 
32 /* libpfm4 includes */
33 #include "papi_libpfm4_events.h"
34 #include "peu_libpfm4_events.h"
35 #include "perfmon/pfmlib.h"
36 #include PEINCLUDE
37 
38 /* Linux-specific includes */
39 #include "mb.h"
40 #include "linux-memory.h"
41 #include "linux-timer.h"
42 #include "linux-common.h"
43 #include "linux-context.h"
44 
46 
47 /* Forward declaration */
49 
50 /* Globals */
52 static int our_cidx;
53 int
55  return our_cidx;
56 }
57 
58 /* Defines for ctx->state */
59 #define PERF_EVENTS_OPENED 0x01
60 #define PERF_EVENTS_RUNNING 0x02
61 
62 static int _peu_set_domain( hwd_control_state_t *ctl, int domain);
63 
64 
65 
66 /******************************************************************/
67 /******** Kernel Version Dependent Routines **********************/
68 /******************************************************************/
69 
70 /* KERNEL_CHECKS_SCHEDUABILITY_UPON_OPEN is a work-around for kernel arch
71  * implementations (e.g. x86) which don't do a static event scheduability
72  * check in sys_perf_event_open.
73  * This was fixed for x86 in the 2.6.33 kernel
74  *
75  * Also! Kernels newer than 2.6.34 will fail in a similar way
76  * if the nmi_watchdog has stolen a performance counter
77  * and we try to use the maximum number of counters.
78  * A sys_perf_event_open() will seem to succeed but will fail
79  * at read time. So re-use this work around code.
80  */
81 static int
83 
84 #if defined(__powerpc__)
85  /* PowerPC not affected by this bug */
86 #elif defined(__mips__)
87  /* MIPS as of kernel 3.1 does not properly detect schedulability */
88  return 1;
89 #else
91  return 1;
92 #endif
93 
94  return 0;
95 }
96 
97 
98 /* The read format on perf_event varies based on various flags that */
99 /* are passed into it. This helper avoids copying this logic */
100 /* multiple places. */
101 static unsigned int
103  unsigned int inherit,
104  int format_group )
105 {
106  unsigned int format = 0;
107 
108  /* if we need read format options for multiplexing, add them now */
109  if (multiplex) {
110  format |= PERF_FORMAT_TOTAL_TIME_ENABLED;
111  format |= PERF_FORMAT_TOTAL_TIME_RUNNING;
112  }
113 
114  /* If we are not using inherit, add the group read options */
115  if (!inherit) {
116  if (format_group) {
117  format |= PERF_FORMAT_GROUP;
118  }
119  }
120 
121  SUBDBG("multiplex: %d, inherit: %d, group_leader: %d, format: %#x\n",
122  multiplex, inherit, format_group, format);
123 
124  return format;
125 }
126 
127 /*****************************************************************/
128 /********* End Kernel-version Dependent Routines ****************/
129 /*****************************************************************/
130 
131 /********************************************************************/
132 /* Low-level perf_event calls */
133 /********************************************************************/
134 
135 /* In case headers aren't new enough to have __NR_perf_event_open */
136 #ifndef __NR_perf_event_open
137 
138 #ifdef __powerpc__
139 #define __NR_perf_event_open 319
140 #elif defined(__x86_64__)
141 #define __NR_perf_event_open 298
142 #elif defined(__i386__)
143 #define __NR_perf_event_open 336
144 #elif defined(__arm__) 366+0x900000
145 #define __NR_perf_event_open
146 #endif
147 
148 #endif
149 
150 static long
151 sys_perf_event_open( struct perf_event_attr *hw_event, pid_t pid, int cpu,
152  int group_fd, unsigned long flags )
153 {
154  int ret;
155 
156  SUBDBG("sys_perf_event_open(hw_event: %p, pid: %d, cpu: %d, group_fd: %d, flags: %lx\n",hw_event,pid,cpu,group_fd,flags);
157  SUBDBG(" type: %d\n",hw_event->type);
158  SUBDBG(" size: %d\n",hw_event->size);
159  SUBDBG(" config: %#"PRIx64" (%"PRIu64")\n",hw_event->config,
160  hw_event->config);
161  SUBDBG(" sample_period: %"PRIu64"\n",hw_event->sample_period);
162  SUBDBG(" sample_type: %"PRIu64"\n",hw_event->sample_type);
163  SUBDBG(" read_format: %"PRIu64"\n",hw_event->read_format);
164  SUBDBG(" disabled: %d\n",hw_event->disabled);
165  SUBDBG(" inherit: %d\n",hw_event->inherit);
166  SUBDBG(" pinned: %d\n",hw_event->pinned);
167  SUBDBG(" exclusive: %d\n",hw_event->exclusive);
168  SUBDBG(" exclude_user: %d\n",hw_event->exclude_user);
169  SUBDBG(" exclude_kernel: %d\n",hw_event->exclude_kernel);
170  SUBDBG(" exclude_hv: %d\n",hw_event->exclude_hv);
171  SUBDBG(" exclude_idle: %d\n",hw_event->exclude_idle);
172  SUBDBG(" mmap: %d\n",hw_event->mmap);
173  SUBDBG(" comm: %d\n",hw_event->comm);
174  SUBDBG(" freq: %d\n",hw_event->freq);
175  SUBDBG(" inherit_stat: %d\n",hw_event->inherit_stat);
176  SUBDBG(" enable_on_exec: %d\n",hw_event->enable_on_exec);
177  SUBDBG(" task: %d\n",hw_event->task);
178  SUBDBG(" watermark: %d\n",hw_event->watermark);
179  SUBDBG(" precise_ip: %d\n",hw_event->precise_ip);
180  SUBDBG(" mmap_data: %d\n",hw_event->mmap_data);
181  SUBDBG(" sample_id_all: %d\n",hw_event->sample_id_all);
182  SUBDBG(" exclude_host: %d\n",hw_event->exclude_host);
183  SUBDBG(" exclude_guest: %d\n",hw_event->exclude_guest);
184  SUBDBG(" exclude_callchain_kernel: %d\n",hw_event->exclude_callchain_kernel);
185  SUBDBG(" exclude_callchain_user: %d\n",hw_event->exclude_callchain_user);
186  SUBDBG(" wakeup_watermark: %d\n",hw_event->wakeup_watermark);
187  SUBDBG(" bp_type: %d\n",hw_event->bp_type);
188  SUBDBG(" config1: %#lx (%lu)\n",hw_event->config1,hw_event->config1);
189  SUBDBG(" config2: %#lx (%lu)\n",hw_event->config2,hw_event->config2);
190  SUBDBG(" branch_sample_type: %lu\n",hw_event->branch_sample_type);
191  SUBDBG(" sample_regs_user: %lu\n",hw_event->sample_regs_user);
192  SUBDBG(" sample_stack_user: %d\n",hw_event->sample_stack_user);
193 
194  ret = syscall( __NR_perf_event_open, hw_event, pid, cpu, group_fd, flags );
195  SUBDBG("Returned %d %d %s\n",ret,
196  ret<0?errno:0,
197  ret<0?strerror(errno):" ");
198  return ret;
199 }
200 
201 
202 static int map_perf_event_errors_to_papi(int perf_event_error) {
203 
204  int ret;
205 
206  /* These mappings are approximate.
207  EINVAL in particular can mean lots of different things */
208  switch(perf_event_error) {
209  case EPERM:
210  case EACCES:
211  ret = PAPI_EPERM;
212  break;
213  case ENODEV:
214  case EOPNOTSUPP:
215  ret = PAPI_ENOSUPP;
216  break;
217  case ENOENT:
218  ret = PAPI_ENOEVNT;
219  break;
220  case ENOSYS:
221  case EAGAIN:
222  case EBUSY:
223  case E2BIG:
224  ret = PAPI_ESYS;
225  break;
226  case ENOMEM:
227  ret = PAPI_ENOMEM;
228  break;
229  case EINVAL:
230  default:
231  ret = PAPI_EINVAL;
232  break;
233  }
234  return ret;
235 }
236 
237 /* Maximum size we ever expect to read from a perf_event fd */
238 /* (this is the number of 64-bit values) */
239 /* We use this to size the read buffers */
240 /* The three is for event count, time_enabled, time_running */
241 /* and the counter term is count value and count id for each */
242 /* possible counter value. */
243 #define READ_BUFFER_SIZE (3 + (2 * PERF_EVENT_MAX_MPX_COUNTERS))
244 
245 
246 
247 /* KERNEL_CHECKS_SCHEDUABILITY_UPON_OPEN is a work-around for kernel arch */
248 /* implementations (e.g. x86 before 2.6.33) which don't do a static event */
249 /* scheduability check in sys_perf_event_open. It is also needed if the */
250 /* kernel is stealing an event, such as when NMI watchdog is enabled. */
251 
252 static int
254 {
255  SUBDBG("ENTER: ctx: %p, ctl: %p\n", ctx, ctl);
256  int retval = 0, cnt = -1;
257  ( void ) ctx; /*unused */
258  long long papi_pe_buffer[READ_BUFFER_SIZE];
259  int i;
260 
261  if (bug_check_scheduability()) {
262 
263  /* If the kernel isn't tracking scheduability right */
264  /* Then we need to start/stop/read to force the event */
265  /* to be scheduled and see if an error condition happens. */
266 
267  /* start all events */
268  for( i = 0; i < ctl->num_events; i++) {
269  retval = ioctl( ctl->events[i].event_fd, PERF_EVENT_IOC_ENABLE, NULL );
270  if (retval == -1) {
271  SUBDBG("EXIT: Enable failed event index: %d, num_events: %d, return PAPI_ESYS\n", i, ctl->num_events);
272  return PAPI_ESYS;
273  }
274  }
275 
276  /* stop all events */
277  for( i = 0; i < ctl->num_events; i++) {
278  retval = ioctl(ctl->events[i].event_fd, PERF_EVENT_IOC_DISABLE, NULL );
279  if (retval == -1) {
280  SUBDBG("EXIT: Disable failed: event index: %d, num_events: %d, return PAPI_ESYS\n", i, ctl->num_events);
281  return PAPI_ESYS;
282  }
283  }
284 
285  /* See if a read of each event returns results */
286  for( i = 0; i < ctl->num_events; i++) {
287  cnt = read( ctl->events[i].event_fd, papi_pe_buffer, sizeof(papi_pe_buffer));
288  if ( cnt == -1 ) {
289  SUBDBG( "EXIT: read failed: event index: %d, num_events: %d, return PAPI_ESYS. Should never happen.\n", i, ctl->num_events);
290  return PAPI_ESYS;
291  }
292 
293  if ( cnt == 0 ) {
294  /* We read 0 bytes if we could not schedule the event */
295  /* The kernel should have detected this at open */
296  /* but various bugs (including NMI watchdog) */
297  /* result in this behavior */
298 
299  SUBDBG( "EXIT: read returned 0: event index: %d, num_events: %d, return PAPI_ECNFLCT.\n", i, ctl->num_events);
300  return PAPI_ECNFLCT;
301  }
302  }
303 
304  /* Reset all of the counters (opened so far) back to zero */
305  /* from the above brief enable/disable call pair. */
306 
307  /* We have to reset all events because reset of group leader */
308  /* does not reset all. */
309  /* we assume that the events are being added one by one and that */
310  /* we do not need to reset higher events (doing so may reset ones */
311  /* that have not been initialized yet. */
312 
313  /* Note... PERF_EVENT_IOC_RESET does not reset time running */
314  /* info if multiplexing, so we should avoid coming here if */
315  /* we are multiplexing the event. */
316  for( i = 0; i < ctl->num_events; i++) {
317  retval=ioctl( ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
318  if (retval == -1) {
319  SUBDBG("EXIT: Reset failed: event index: %d, num_events: %d, return PAPI_ESYS\n", i, ctl->num_events);
320  return PAPI_ESYS;
321  }
322  }
323  }
324  SUBDBG("EXIT: return PAPI_OK\n");
325  return PAPI_OK;
326 }
327 
328 
329 /* Open all events in the control state */
330 static int
332 {
333 
334  int i, ret = PAPI_OK;
335  long pid;
336 
337  if (ctl->granularity==PAPI_GRN_SYS) {
338  pid = -1;
339  }
340  else {
341  pid = ctl->tid;
342  }
343 
344  for( i = 0; i < ctl->num_events; i++ ) {
345 
346  ctl->events[i].event_opened=0;
347 
348  /* set up the attr structure. We don't set up all fields here */
349  /* as some have already been set up previously. */
350 
351 /*
352  * The following code controls how the uncore component interfaces with the
353  * kernel for uncore events. The code inside the ifdef will use grouping of
354  * uncore events which can make the cost of reading the results more efficient.
355  * The problem with it is that the uncore component supports 20 different uncore
356  * PMU's. The kernel requires that all events in a group must be for the same PMU.
357  * This means that with grouping enabled papi applications can count events on only
358  * one of the 20 PMU's during a run.
359  *
360  * The code inside the else clause treats each event in the event set as
361  * independent. When running in this mode the kernel allows the papi multiple
362  * uncore PMU's at the same time.
363  *
364  * Example:
365  * An application wants to measure all the L3 cache write requests.
366  * The event to do this is part of a cbox pmu (there are 8 cbox pmu's).
367  * When built with the code in the ifdef, the application would have to be
368  * run 8 times and count write requests from one pmu at a time.
369  * When built with the code in the else, the write requests in all 8 cbox
370  * pmu's could be counted in the same run.
371  *
372  */
373 // #define GROUPIT 1 // remove the comment on this line to force event grouping
374 #ifdef GROUPIT
375  /* group leader (event 0) is special */
376  /* If we're multiplexed, everyone is a group leader */
377  if (( i == 0 ) || (ctl->multiplexed)) {
378  ctl->events[i].attr.pinned = !ctl->multiplexed;
379  ctl->events[i].attr.disabled = 1;
380  ctl->events[i].group_leader_fd=-1;
381  ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed,
382  ctl->inherit,
383  !ctl->multiplexed );
384  } else {
385  ctl->events[i].attr.pinned=0;
386  ctl->events[i].attr.disabled = 0;
387  ctl->events[i].group_leader_fd=ctl->events[0].event_fd,
388  ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed,
389  ctl->inherit,
390  0 );
391  }
392 #else
393  ctl->events[i].attr.pinned = !ctl->multiplexed;
394  ctl->events[i].attr.disabled = 1;
395  ctl->inherit = 1;
396  ctl->events[i].group_leader_fd=-1;
397  ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed, ctl->inherit, 0 );
398 #endif
399 
400 
401  /* try to open */
402  ctl->events[i].event_fd = sys_perf_event_open( &ctl->events[i].attr,
403  pid,
404  ctl->events[i].cpu,
405  ctl->events[i].group_leader_fd,
406  0 /* flags */
407  );
408 
409  /* Try to match Linux errors to PAPI errors */
410  if ( ctl->events[i].event_fd == -1 ) {
411  SUBDBG("sys_perf_event_open returned error on event #%d."
412  " Error: %s\n",
413  i, strerror( errno ) );
415 
416  goto open_peu_cleanup;
417  }
418 
419  SUBDBG ("sys_perf_event_open: tid: %ld, cpu_num: %d,"
420  " group_leader/fd: %d, event_fd: %d,"
421  " read_format: %"PRIu64"\n",
422  pid, ctl->events[i].cpu, ctl->events[i].group_leader_fd,
423  ctl->events[i].event_fd, ctl->events[i].attr.read_format);
424 
425  ctl->events[i].event_opened=1;
426  }
427 
428 
429  /* in many situations the kernel will indicate we opened fine */
430  /* yet things will fail later. So we need to double check */
431  /* we actually can use the events we've set up. */
432 
433  /* This is not necessary if we are multiplexing, and in fact */
434  /* we cannot do this properly if multiplexed because */
435  /* PERF_EVENT_IOC_RESET does not reset the time running info */
436  if (!ctl->multiplexed) {
437  ret = check_scheduability( ctx, ctl);
438 
439  if ( ret != PAPI_OK ) {
440  /* the last event did open, so we need to bump the counter */
441  /* before doing the cleanup */
442  i++;
443  goto open_peu_cleanup;
444  }
445  }
446 
447  /* Now that we've successfully opened all of the events, do whatever */
448  /* "tune-up" is needed to attach the mmap'd buffers, signal handlers, */
449  /* and so on. */
450  for ( i = 0; i < ctl->num_events; i++ ) {
451 
452  /* No sampling if uncore */
453  ctl->events[i].mmap_buf = NULL;
454  }
455 
456  /* Set num_evts only if completely successful */
457  ctx->state |= PERF_EVENTS_OPENED;
458 
459  return PAPI_OK;
460 
461 open_peu_cleanup:
462  /* We encountered an error, close up the fds we successfully opened. */
463  /* We go backward in an attempt to close group leaders last, although */
464  /* That's probably not strictly necessary. */
465  while ( i > 0 ) {
466  i--;
467  if (ctl->events[i].event_fd>=0) {
468  close( ctl->events[i].event_fd );
469  ctl->events[i].event_opened=0;
470  }
471  }
472 
473  return ret;
474 }
475 
476 /* Close all of the opened events */
477 static int
479 {
480  int i;
481  int num_closed=0;
482  int events_not_opened=0;
483 
484  /* should this be a more serious error? */
485  if ( ctx->state & PERF_EVENTS_RUNNING ) {
486  SUBDBG("Closing without stopping first\n");
487  }
488 
489  /* Close child events first */
490  for( i=0; i<ctl->num_events; i++ ) {
491 
492  if (ctl->events[i].event_opened) {
493 
494  if (ctl->events[i].group_leader_fd!=-1) {
495  if ( ctl->events[i].mmap_buf ) {
496  if ( munmap ( ctl->events[i].mmap_buf,
497  ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
498  PAPIERROR( "munmap of fd = %d returned error: %s",
499  ctl->events[i].event_fd, strerror( errno ) );
500  return PAPI_ESYS;
501  }
502  }
503 
504  if ( close( ctl->events[i].event_fd ) ) {
505  PAPIERROR( "close of fd = %d returned error: %s",
506  ctl->events[i].event_fd, strerror( errno ) );
507  return PAPI_ESYS;
508  } else {
509  num_closed++;
510  }
511  ctl->events[i].event_opened=0;
512  }
513  }
514  else {
515  events_not_opened++;
516  }
517  }
518 
519  /* Close the group leaders last */
520  for( i=0; i<ctl->num_events; i++ ) {
521 
522  if (ctl->events[i].event_opened) {
523 
524  if (ctl->events[i].group_leader_fd==-1) {
525  if ( ctl->events[i].mmap_buf ) {
526  if ( munmap ( ctl->events[i].mmap_buf,
527  ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
528  PAPIERROR( "munmap of fd = %d returned error: %s",
529  ctl->events[i].event_fd, strerror( errno ) );
530  return PAPI_ESYS;
531  }
532  }
533 
534 
535  if ( close( ctl->events[i].event_fd ) ) {
536  PAPIERROR( "close of fd = %d returned error: %s",
537  ctl->events[i].event_fd, strerror( errno ) );
538  return PAPI_ESYS;
539  } else {
540  num_closed++;
541  }
542  ctl->events[i].event_opened=0;
543  }
544  }
545  }
546 
547 
548  if (ctl->num_events!=num_closed) {
549  if (ctl->num_events!=(num_closed+events_not_opened)) {
550  PAPIERROR("Didn't close all events: "
551  "Closed %d Not Opened: %d Expected %d\n",
552  num_closed,events_not_opened,ctl->num_events);
553  return PAPI_EBUG;
554  }
555  }
556 
557  ctl->num_events=0;
558 
559  ctx->state &= ~PERF_EVENTS_OPENED;
560 
561  return PAPI_OK;
562 }
563 
564 
565 
566 
567 /********************************************************************/
568 /* Component Interface */
569 /********************************************************************/
570 
571 
572 
573 /* Initialize a thread */
574 int
576 {
577 
578  pe_context_t *pe_ctx = ( pe_context_t *) hwd_ctx;
579 
580  /* clear the context structure and mark as initialized */
581  memset( pe_ctx, 0, sizeof ( pe_context_t ) );
582  pe_ctx->initialized=1;
583 
585  pe_ctx->cidx=our_cidx;
586 
587  return PAPI_OK;
588 }
589 
590 /* Initialize a new control state */
591 int
593 {
594  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
595 
596  /* clear the contents */
597  memset( pe_ctl, 0, sizeof ( pe_control_t ) );
598 
599  /* Set the default domain */
600  _peu_set_domain( ctl, _perf_event_uncore_vector.cmp_info.default_domain );
601 
602  /* Set the default granularity */
603  pe_ctl->granularity=_perf_event_uncore_vector.cmp_info.default_granularity;
604 
605  pe_ctl->cidx=our_cidx;
606 
607  /* Set cpu number in the control block to show events */
608  /* are not tied to specific cpu */
609  pe_ctl->cpu = -1;
610  return PAPI_OK;
611 }
612 
613 
614 
615 /* Initialize the perf_event uncore component */
616 int
618 {
619 
620  int retval;
621  int paranoid_level;
622 
623  FILE *fff;
624 
625  our_cidx=cidx;
626 
627  /* The is the official way to detect if perf_event support exists */
628  /* The file is called perf_counter_paranoid on 2.6.31 */
629  /* currently we are lazy and do not support 2.6.31 kernels */
630 
631  fff=fopen("/proc/sys/kernel/perf_event_paranoid","r");
632  if (fff==NULL) {
633  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
634  "perf_event support not detected",PAPI_MAX_STR_LEN);
635  return PAPI_ENOCMP;
636  }
637  retval=fscanf(fff,"%d",&paranoid_level);
638  if (retval!=1) fprintf(stderr,"Error reading paranoid level\n");
639  fclose(fff);
640 
641 
642  /* Run the libpfm4-specific setup */
643 
644  retval = _papi_libpfm4_init(_papi_hwd[cidx]);
645  if (retval) {
646  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
647  "Error initializing libpfm4",PAPI_MAX_STR_LEN);
648  return PAPI_ENOCMP;
649  }
650 
651 
652  /* Run the uncore specific libpfm4 setup */
653 
654  retval = _peu_libpfm4_init(_papi_hwd[cidx],
657  if (retval) {
658  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
659  "Error setting up libpfm4",PAPI_MAX_STR_LEN);
660  return PAPI_ENOCMP;
661  }
662 
663  /* Check if no uncore events found */
664 
665  if (_papi_hwd[cidx]->cmp_info.num_native_events==0) {
666  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
667  "No uncore PMUs or events found",PAPI_MAX_STR_LEN);
668  return PAPI_ENOCMP;
669  }
670 
671  /* Check if we have enough permissions for uncore */
672 
673  /* 2 means no kernel measurements allowed */
674  /* 1 means normal counter access */
675  /* 0 means you can access CPU-specific data */
676  /* -1 means no restrictions */
677 
678  if ((paranoid_level>0) && (getuid()!=0)) {
679  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
680  "Insufficient permissions for uncore access. Set /proc/sys/kernel/perf_event_paranoid to 0 or run as root.",
682  return PAPI_ENOCMP;
683  }
684 
685  return PAPI_OK;
686 
687 }
688 
689 /* Shutdown the perf_event component */
691 
692  /* deallocate our event table */
693  _peu_libpfm4_shutdown(&_perf_event_uncore_vector, &uncore_native_event_table);
694 
695  /* Shutdown libpfm4 */
697 
698  return PAPI_OK;
699 }
700 
701 /* This function clears the current contents of the control structure and
702  updates it with whatever resources are allocated for all the native events
703  in the native info structure array. */
704 
705 int
708  int count, hwd_context_t *ctx )
709 {
710  int i;
711  int j;
712  int ret;
713  int skipped_events=0;
714  struct native_event_t *ntv_evt;
715  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
716  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
717 
718  /* close all of the existing fds and start over again */
719  /* In theory we could have finer-grained control and know if */
720  /* things were changed, but it's easier to tear things down and rebuild. */
721  close_pe_events( pe_ctx, pe_ctl );
722 
723  /* Calling with count==0 should be OK, it's how things are deallocated */
724  /* when an eventset is destroyed. */
725  if ( count == 0 ) {
726  SUBDBG( "Called with count == 0\n" );
727  return PAPI_OK;
728  }
729 
730  /* set up all the events */
731  for( i = 0; i < count; i++ ) {
732  if ( native ) {
733  // get the native event pointer used for this papi event
734  int ntv_idx = _papi_hwi_get_ntv_idx((unsigned)(native[i].ni_papi_code));
735  if (ntv_idx < -1) {
736  SUBDBG("papi_event_code: %#x known by papi but not by the component\n", native[i].ni_papi_code);
737  continue;
738  }
739  // if native index is -1, then we have an event without a mask and need to find the right native index to use
740  if (ntv_idx == -1) {
741  // find the native event index we want by matching for the right papi event code
742  for (j=0 ; j<pe_ctx->event_table->num_native_events ; j++) {
743  if (pe_ctx->event_table->native_events[j].papi_event_code == native[i].ni_papi_code) {
744  ntv_idx = j;
745  }
746  }
747  }
748 
749  // if native index is still negative, we did not find event we wanted so just return error
750  if (ntv_idx < 0) {
751  SUBDBG("papi_event_code: %#x not found in native event tables\n", native[i].ni_papi_code);
752  continue;
753  }
754 
755  // this native index is positive so there was a mask with the event, the ntv_idx identifies which native event to use
756  ntv_evt = (struct native_event_t *)(&(pe_ctx->event_table->native_events[ntv_idx]));
757 
758  SUBDBG("ntv_evt: %p\n", ntv_evt);
759 
760  SUBDBG("i: %d, pe_ctx->event_table->num_native_events: %d\n", i, pe_ctx->event_table->num_native_events);
761 
762  // Move this events hardware config values and other attributes to the perf_events attribute structure
763  memcpy (&pe_ctl->events[i].attr, &ntv_evt->attr, sizeof(perf_event_attr_t));
764 
765  // may need to update the attribute structure with information from event set level domain settings (values set by PAPI_set_domain)
766  // only done if the event mask which controls each counting domain was not provided
767 
768  // get pointer to allocated name, will be NULL when adding preset events to event set
769  char *aName = ntv_evt->allocated_name;
770  if ((aName == NULL) || (strstr(aName, ":u=") == NULL)) {
771  SUBDBG("set exclude_user attribute from eventset level domain flags, encode: %d, eventset: %d\n", pe_ctl->events[i].attr.exclude_user, !(pe_ctl->domain & PAPI_DOM_USER));
772  pe_ctl->events[i].attr.exclude_user = !(pe_ctl->domain & PAPI_DOM_USER);
773  }
774  if ((aName == NULL) || (strstr(aName, ":k=") == NULL)) {
775  SUBDBG("set exclude_kernel attribute from eventset level domain flags, encode: %d, eventset: %d\n", pe_ctl->events[i].attr.exclude_kernel, !(pe_ctl->domain & PAPI_DOM_KERNEL));
776  pe_ctl->events[i].attr.exclude_kernel = !(pe_ctl->domain & PAPI_DOM_KERNEL);
777  }
778 
779  // set the cpu number provided with an event mask if there was one (will be -1 if mask not provided)
780  pe_ctl->events[i].cpu = ntv_evt->cpu;
781  // if cpu event mask not provided, then set the cpu to use to what may have been set on call to PAPI_set_opt (will still be -1 if not called)
782  if (pe_ctl->events[i].cpu == -1) {
783  pe_ctl->events[i].cpu = pe_ctl->cpu;
784  }
785  } else {
786  // This case happens when called from _pe_set_overflow and _pe_ctl
787  // Those callers put things directly into the pe_ctl structure so it is already set for the open call
788  }
789 
790  // Copy the inherit flag into the attribute block that will be passed to the kernel
791  pe_ctl->events[i].attr.inherit = pe_ctl->inherit;
792 
793  /* Set the position in the native structure */
794  /* We just set up events linearly */
795  if ( native ) {
796  native[i].ni_position = i;
797  SUBDBG( "&native[%d]: %p, ni_papi_code: %#x, ni_event: %#x, ni_position: %d, ni_owners: %d\n",
798  i, &(native[i]), native[i].ni_papi_code, native[i].ni_event, native[i].ni_position, native[i].ni_owners);
799  }
800  }
801 
802  if (count <= skipped_events) {
803  SUBDBG("EXIT: No events to count, they all contained invalid umasks\n");
804  return PAPI_ENOEVNT;
805  }
806 
807  pe_ctl->num_events = count - skipped_events;
808 
809  /* actuall open the events */
810  /* (why is this a separate function?) */
811  ret = open_pe_events( pe_ctx, pe_ctl );
812  if ( ret != PAPI_OK ) {
813  SUBDBG("open_pe_events failed\n");
814  /* Restore values ? */
815  return ret;
816  }
817 
818  SUBDBG( "EXIT: PAPI_OK\n" );
819  return PAPI_OK;
820 }
821 
822 /********************************************************************/
823 /********************************************************************/
824 /* Start with functions that are exported via the module interface */
825 /********************************************************************/
826 /********************************************************************/
827 
828 
829 /* set the domain. perf_events allows per-event control of this, papi allows it to be set at the event level or at the event set level. */
830 /* this will set the event set level domain values but they only get used if no event level domain mask (u= or k=) was specified. */
831 static int
833 {
834  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
835 
836  SUBDBG("old control domain %d, new domain %d\n",
837  pe_ctl->domain,domain);
838 
839  pe_ctl->domain = domain;
840  return PAPI_OK;
841 }
842 
843 /* Shutdown a thread */
844 int
846 {
847  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
848 
849  pe_ctx->initialized=0;
850 
851  return PAPI_OK;
852 }
853 
854 
855 /* reset the hardware counters */
856 /* Note: PAPI_reset() does not necessarily call this */
857 /* unless the events are actually running. */
858 int
860 {
861  int i, ret;
862  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
863 
864  ( void ) ctx; /*unused */
865 
866  /* We need to reset all of the events, not just the group leaders */
867  for( i = 0; i < pe_ctl->num_events; i++ ) {
868  ret = ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
869  if ( ret == -1 ) {
870  PAPIERROR("ioctl(%d, PERF_EVENT_IOC_RESET, NULL) "
871  "returned error, Linux says: %s",
872  pe_ctl->events[i].event_fd, strerror( errno ) );
873  return PAPI_ESYS;
874  }
875  }
876 
877  return PAPI_OK;
878 }
879 
880 
881 /* write (set) the hardware counters */
882 /* Current we do not support this. */
883 int
885  long long *from )
886 {
887  ( void ) ctx; /*unused */
888  ( void ) ctl; /*unused */
889  ( void ) from; /*unused */
890  /*
891  * Counters cannot be written. Do we need to virtualize the
892  * counters so that they can be written, or perhaps modify code so that
893  * they can be written? FIXME ?
894  */
895 
896  return PAPI_ENOSUPP;
897 }
898 
899 /*
900  * perf_event provides a complicated read interface.
901  * the info returned by read() varies depending on whether
902  * you have PERF_FORMAT_GROUP, PERF_FORMAT_TOTAL_TIME_ENABLED,
903  * PERF_FORMAT_TOTAL_TIME_RUNNING, or PERF_FORMAT_ID set
904  *
905  * To simplify things we just always ask for everything. This might
906  * lead to overhead when reading more than we need, but it makes the
907  * read code a lot simpler than the original implementation we had here.
908  *
909  * For more info on the layout see include/linux/perf_event.h
910  *
911  */
912 
913 int
915  long long **events, int flags )
916 {
917  SUBDBG("ENTER: ctx: %p, ctl: %p, events: %p, flags: %#x\n", ctx, ctl, events, flags);
918 
919  ( void ) flags; /*unused */
920  int i, ret = -1;
921  /* pe_context_t *pe_ctx = ( pe_context_t *) ctx; */
922  (void) ctx; /*unused*/
923  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
924  long long papi_pe_buffer[READ_BUFFER_SIZE];
925  long long tot_time_running, tot_time_enabled, scale;
926 
927  /* Handle case where we are multiplexing */
928  if (pe_ctl->multiplexed) {
929 
930  /* currently we handle multiplexing by having individual events */
931  /* so we read from each in turn. */
932 
933  for ( i = 0; i < pe_ctl->num_events; i++ ) {
934 
935  ret = read( pe_ctl->events[i].event_fd, papi_pe_buffer,
936  sizeof ( papi_pe_buffer ) );
937  if ( ret == -1 ) {
938  PAPIERROR("read returned an error: ", strerror( errno ));
939  SUBDBG("EXIT: PAPI_ESYS\n");
940  return PAPI_ESYS;
941  }
942 
943  /* We should read 3 64-bit values from the counter */
944  if (ret<(signed)(3*sizeof(long long))) {
945  PAPIERROR("Error! short read!\n");
946  SUBDBG("EXIT: PAPI_ESYS\n");
947  return PAPI_ESYS;
948  }
949 
950  SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
951  pe_ctl->events[i].event_fd,
952  (long)pe_ctl->tid, pe_ctl->events[i].cpu, ret);
953  SUBDBG("read: %lld %lld %lld\n",papi_pe_buffer[0],
954  papi_pe_buffer[1],papi_pe_buffer[2]);
955 
956  tot_time_enabled = papi_pe_buffer[1];
957  tot_time_running = papi_pe_buffer[2];
958 
959  SUBDBG("count[%d] = (papi_pe_buffer[%d] %lld * "
960  "tot_time_enabled %lld) / tot_time_running %lld\n",
961  i, 0,papi_pe_buffer[0],
962  tot_time_enabled,tot_time_running);
963 
964  if (tot_time_running == tot_time_enabled) {
965  /* No scaling needed */
966  pe_ctl->counts[i] = papi_pe_buffer[0];
967  } else if (tot_time_running && tot_time_enabled) {
968  /* Scale factor of 100 to avoid overflows when computing */
969  /*enabled/running */
970 
971  scale = (tot_time_enabled * 100LL) / tot_time_running;
972  scale = scale * papi_pe_buffer[0];
973  scale = scale / 100LL;
974  pe_ctl->counts[i] = scale;
975  } else {
976  /* This should not happen, but Phil reports it sometime does. */
977  SUBDBG("perf_event kernel bug(?) count, enabled, "
978  "running: %lld, %lld, %lld\n",
979  papi_pe_buffer[0],tot_time_enabled,
980  tot_time_running);
981 
982  pe_ctl->counts[i] = papi_pe_buffer[0];
983  }
984  }
985  }
986 
987  /* Handle cases where we cannot use FORMAT GROUP */
988  else if (pe_ctl->inherit) {
989 
990  /* we must read each counter individually */
991  for ( i = 0; i < pe_ctl->num_events; i++ ) {
992 
993  ret = read( pe_ctl->events[i].event_fd, papi_pe_buffer,
994  sizeof ( papi_pe_buffer ) );
995  if ( ret == -1 ) {
996  PAPIERROR("read returned an error: ", strerror( errno ));
997  SUBDBG("EXIT: PAPI_ESYS\n");
998  return PAPI_ESYS;
999  }
1000 
1001  /* we should read one 64-bit value from each counter */
1002  if (ret!=sizeof(long long)) {
1003  PAPIERROR("Error! short read!\n");
1004  PAPIERROR("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
1005  pe_ctl->events[i].event_fd,
1006  (long)pe_ctl->tid, pe_ctl->events[i].cpu, ret);
1007  SUBDBG("EXIT: PAPI_ESYS\n");
1008  return PAPI_ESYS;
1009  }
1010 
1011  SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
1012  pe_ctl->events[i].event_fd, (long)pe_ctl->tid,
1013  pe_ctl->events[i].cpu, ret);
1014  SUBDBG("read: %lld\n",papi_pe_buffer[0]);
1015 
1016  pe_ctl->counts[i] = papi_pe_buffer[0];
1017  }
1018  }
1019 
1020 
1021  /* Handle cases where we are using FORMAT_GROUP */
1022  /* We assume only one group leader, in position 0 */
1023 
1024  else {
1025  if (pe_ctl->events[0].group_leader_fd!=-1) {
1026  PAPIERROR("Was expecting group leader!\n");
1027  }
1028 
1029  ret = read( pe_ctl->events[0].event_fd, papi_pe_buffer,
1030  sizeof ( papi_pe_buffer ) );
1031 
1032  if ( ret == -1 ) {
1033  PAPIERROR("read returned an error: ", strerror( errno ));
1034  SUBDBG("EXIT: PAPI_ESYS\n");
1035  return PAPI_ESYS;
1036  }
1037 
1038  /* we read 1 64-bit value (number of events) then */
1039  /* num_events more 64-bit values that hold the counts */
1040  if (ret<(signed)((1+pe_ctl->num_events)*sizeof(long long))) {
1041  PAPIERROR("Error! short read!\n");
1042  SUBDBG("EXIT: PAPI_ESYS\n");
1043  return PAPI_ESYS;
1044  }
1045 
1046  SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
1047  pe_ctl->events[0].event_fd,
1048  (long)pe_ctl->tid, pe_ctl->events[0].cpu, ret);
1049  {
1050  int j;
1051  for(j=0;j<ret/8;j++) {
1052  SUBDBG("read %d: %lld\n",j,papi_pe_buffer[j]);
1053  }
1054  }
1055 
1056  /* Make sure the kernel agrees with how many events we have */
1057  if (papi_pe_buffer[0]!=pe_ctl->num_events) {
1058  PAPIERROR("Error! Wrong number of events!\n");
1059  SUBDBG("EXIT: PAPI_ESYS\n");
1060  return PAPI_ESYS;
1061  }
1062 
1063  /* put the count values in their proper location */
1064  for(i=0;i<pe_ctl->num_events;i++) {
1065  pe_ctl->counts[i] = papi_pe_buffer[1+i];
1066  }
1067  }
1068 
1069  /* point PAPI to the values we read */
1070  *events = pe_ctl->counts;
1071 
1072  SUBDBG("EXIT: PAPI_OK\n");
1073  return PAPI_OK;
1074 }
1075 
1076 /* Start counting events */
1077 int
1079 {
1080  int ret;
1081  int i;
1082  int did_something = 0;
1083  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
1084  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
1085 
1086  /* Reset the counters first. Is this necessary? */
1087  ret = _peu_reset( pe_ctx, pe_ctl );
1088  if ( ret ) {
1089  return ret;
1090  }
1091 
1092  /* Enable all of the group leaders */
1093  /* All group leaders have a group_leader_fd of -1 */
1094  for( i = 0; i < pe_ctl->num_events; i++ ) {
1095  if (pe_ctl->events[i].group_leader_fd == -1) {
1096  SUBDBG("ioctl(enable): fd: %d\n", pe_ctl->events[i].event_fd);
1097  ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_ENABLE, NULL) ;
1098 
1099  /* ioctls always return -1 on failure */
1100  if (ret == -1) {
1101  PAPIERROR("ioctl(PERF_EVENT_IOC_ENABLE) failed.\n");
1102  return PAPI_ESYS;
1103  }
1104 
1105  did_something++;
1106  }
1107  }
1108 
1109  if (!did_something) {
1110  PAPIERROR("Did not enable any counters.\n");
1111  return PAPI_EBUG;
1112  }
1113 
1114  pe_ctx->state |= PERF_EVENTS_RUNNING;
1115 
1116  return PAPI_OK;
1117 
1118 }
1119 
1120 /* Stop all of the counters */
1121 int
1123 {
1124 
1125  int ret;
1126  int i;
1127  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
1128  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
1129 
1130  /* Just disable the group leaders */
1131  for ( i = 0; i < pe_ctl->num_events; i++ ) {
1132  if ( pe_ctl->events[i].group_leader_fd == -1 ) {
1133  ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_DISABLE, NULL);
1134  if ( ret == -1 ) {
1135  PAPIERROR( "ioctl(%d, PERF_EVENT_IOC_DISABLE, NULL) "
1136  "returned error, Linux says: %s",
1137  pe_ctl->events[i].event_fd, strerror( errno ) );
1138  return PAPI_EBUG;
1139  }
1140  }
1141  }
1142 
1143  pe_ctx->state &= ~PERF_EVENTS_RUNNING;
1144 
1145  return PAPI_OK;
1146 }
1147 
1148 /* Set various options on a control state */
1149 int
1150 _peu_ctl( hwd_context_t *ctx, int code, _papi_int_option_t *option )
1151 {
1152  int ret;
1153  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
1154  pe_control_t *pe_ctl = NULL;
1155 
1156  switch ( code ) {
1157  case PAPI_MULTIPLEX:
1158  pe_ctl = ( pe_control_t * ) ( option->multiplex.ESI->ctl_state );
1159 
1160  pe_ctl->multiplexed = 1;
1161  ret = _peu_update_control_state( pe_ctl, NULL,
1162  pe_ctl->num_events, pe_ctx );
1163  if (ret != PAPI_OK) {
1164  pe_ctl->multiplexed = 0;
1165  }
1166  return ret;
1167 
1168  case PAPI_ATTACH:
1169  pe_ctl = ( pe_control_t * ) ( option->attach.ESI->ctl_state );
1170 
1171  pe_ctl->tid = option->attach.tid;
1172 
1173  /* If events have been already been added, something may */
1174  /* have been done to the kernel, so update */
1175  ret =_peu_update_control_state( pe_ctl, NULL,
1176  pe_ctl->num_events, pe_ctx);
1177 
1178  return ret;
1179 
1180  case PAPI_DETACH:
1181  pe_ctl = ( pe_control_t *) ( option->attach.ESI->ctl_state );
1182 
1183  pe_ctl->tid = 0;
1184  return PAPI_OK;
1185 
1186  case PAPI_CPU_ATTACH:
1187  pe_ctl = ( pe_control_t *) ( option->cpu.ESI->ctl_state );
1188 
1189  /* this tells the kernel not to count for a thread */
1190  /* should we warn if we try to set both? perf_event */
1191  /* will reject it. */
1192  pe_ctl->tid = -1;
1193 
1194  pe_ctl->cpu = option->cpu.cpu_num;
1195 
1196  return PAPI_OK;
1197 
1198  case PAPI_DOMAIN:
1199  pe_ctl = ( pe_control_t *) ( option->domain.ESI->ctl_state );
1200 
1201  /* looks like we are allowed, so set event set level counting domains */
1202  pe_ctl->domain = option->domain.domain;
1203  return PAPI_OK;
1204 
1205  case PAPI_GRANUL:
1206  pe_ctl = (pe_control_t *) ( option->granularity.ESI->ctl_state );
1207 
1208  /* FIXME: we really don't support this yet */
1209 
1210  switch ( option->granularity.granularity ) {
1211  case PAPI_GRN_PROCG:
1212  case PAPI_GRN_SYS_CPU:
1213  case PAPI_GRN_PROC:
1214  return PAPI_ECMP;
1215 
1216  /* Currently we only support thread and CPU granularity */
1217  case PAPI_GRN_SYS:
1218  pe_ctl->granularity=PAPI_GRN_SYS;
1219  break;
1220 
1221  case PAPI_GRN_THR:
1222  pe_ctl->granularity=PAPI_GRN_THR;
1223  break;
1224 
1225 
1226  default:
1227  return PAPI_EINVAL;
1228  }
1229  return PAPI_OK;
1230 
1231  case PAPI_INHERIT:
1232  pe_ctl = (pe_control_t *) ( option->inherit.ESI->ctl_state );
1233 
1234  if (option->inherit.inherit) {
1235  /* children will inherit counters */
1236  pe_ctl->inherit = 1;
1237  } else {
1238  /* children won't inherit counters */
1239  pe_ctl->inherit = 0;
1240  }
1241  return PAPI_OK;
1242 
1243  case PAPI_DATA_ADDRESS:
1244  return PAPI_ENOSUPP;
1245 
1246  case PAPI_INSTR_ADDRESS:
1247  return PAPI_ENOSUPP;
1248 
1249  case PAPI_DEF_ITIMER:
1250  return PAPI_ENOSUPP;
1251 
1252  case PAPI_DEF_MPX_NS:
1253  return PAPI_ENOSUPP;
1254 
1255  case PAPI_DEF_ITIMER_NS:
1256  return PAPI_ENOSUPP;
1257 
1258  default:
1259  return PAPI_ENOSUPP;
1260  }
1261 }
1262 
1263 
1264 int
1265 _peu_ntv_enum_events( unsigned int *PapiEventCode, int modifier )
1266 {
1267 
1268  if (_perf_event_uncore_vector.cmp_info.disabled) return PAPI_ENOEVNT;
1269 
1270 
1271  return _peu_libpfm4_ntv_enum_events(PapiEventCode, modifier,
1273 }
1274 
1275 int
1276 _peu_ntv_name_to_code( char *name, unsigned int *event_code) {
1277 
1278  if (_perf_event_uncore_vector.cmp_info.disabled) return PAPI_ENOEVNT;
1279 
1280  return _peu_libpfm4_ntv_name_to_code(name,event_code,
1282 }
1283 
1284 int
1285 _peu_ntv_code_to_name(unsigned int EventCode,
1286  char *ntv_name, int len) {
1287 
1288  if (_perf_event_uncore_vector.cmp_info.disabled) return PAPI_ENOEVNT;
1289 
1290  return _peu_libpfm4_ntv_code_to_name(EventCode,
1291  ntv_name, len,
1293 }
1294 
1295 int
1296 _peu_ntv_code_to_descr( unsigned int EventCode,
1297  char *ntv_descr, int len) {
1298 
1299  if (_perf_event_uncore_vector.cmp_info.disabled) return PAPI_ENOEVNT;
1300 
1301  return _peu_libpfm4_ntv_code_to_descr(EventCode,ntv_descr,len,
1303 }
1304 
1305 int
1306 _peu_ntv_code_to_info(unsigned int EventCode,
1307  PAPI_event_info_t *info) {
1308 
1309  if (_perf_event_uncore_vector.cmp_info.disabled) return PAPI_ENOEVNT;
1310 
1311  return _peu_libpfm4_ntv_code_to_info(EventCode, info,
1313 }
1314 
1315 /* Our component vector */
1316 
1317 papi_vector_t _perf_event_uncore_vector = {
1318  .cmp_info = {
1319  /* component information (unspecified values initialized to 0) */
1320  .name = "perf_event_uncore",
1321  .short_name = "peu",
1322  .version = "5.0",
1323  .description = "Linux perf_event CPU uncore and northbridge",
1324 
1325  .default_domain = PAPI_DOM_ALL,
1326  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR,
1327  .default_granularity = PAPI_GRN_SYS,
1328  .available_granularities = PAPI_GRN_SYS,
1329 
1330  .num_mpx_cntrs = PERF_EVENT_MAX_MPX_COUNTERS,
1331 
1332  /* component specific cmp_info initializations */
1333  .fast_virtual_timer = 0,
1334  .attach = 1,
1335  .attach_must_ptrace = 1,
1336  .cpu = 1,
1337  .inherit = 1,
1338  .cntr_umasks = 1,
1339 
1340  },
1341 
1342  /* sizes of framework-opaque component-private structures */
1343  .size = {
1344  .context = sizeof ( pe_context_t ),
1345  .control_state = sizeof ( pe_control_t ),
1346  .reg_value = sizeof ( int ),
1347  .reg_alloc = sizeof ( int ),
1348  },
1349 
1350  /* function pointers in this component */
1351  .init_component = _peu_init_component,
1352  .shutdown_component = _peu_shutdown_component,
1353  .init_thread = _peu_init_thread,
1354  .init_control_state = _peu_init_control_state,
1355  .start = _peu_start,
1356  .stop = _peu_stop,
1357  .read = _peu_read,
1358  .shutdown_thread = _peu_shutdown_thread,
1359  .ctl = _peu_ctl,
1360  .update_control_state = _peu_update_control_state,
1361  .set_domain = _peu_set_domain,
1362  .reset = _peu_reset,
1363  .write = _peu_write,
1364 
1365  /* from counter name mapper */
1366  .ntv_enum_events = _peu_ntv_enum_events,
1367  .ntv_name_to_code = _peu_ntv_name_to_code,
1368  .ntv_code_to_name = _peu_ntv_code_to_name,
1369  .ntv_code_to_descr = _peu_ntv_code_to_descr,
1370  .ntv_code_to_info = _peu_ntv_code_to_info,
1371 };
1372 
1373 
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:626
i inherit inherit
#define PAPI_ENOEVNT
Definition: papi.h:258
static int our_cidx
int _peu_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:225
memset(eventId, 0, size)
int _peu_ntv_name_to_code(char *name, unsigned int *event_code)
static int open_pe_events(pe_context_t *ctx, pe_control_t *ctl)
long long counts[PERF_EVENT_MAX_MPX_COUNTERS]
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
_papi_int_inherit_t inherit
int errno
int close(int fd)
Definition: appio.c:175
int _peu_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len)
#define PAPI_CPU_ATTACH
Definition: papi.h:455
int _peu_shutdown_component(void)
#define PERF_EVENT_MAX_MPX_COUNTERS
Definition: perf_event_lib.h:5
EventSetInfo_t * ESI
struct native_event_t * native_events
unsigned int granularity
long long flags
Definition: iozone.c:12330
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:453
EventSetInfo_t * ESI
int _papi_libpfm4_init(papi_vector_t *my_vector)
static int map_perf_event_errors_to_papi(int perf_event_error)
#define PAPI_INSTR_ADDRESS
Definition: papi.h:451
int _peu_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int bug_check_scheduability(void)
#define PAPI_DEF_MPX_NS
Definition: papi.h:434
cpu
Definition: iozone.c:3872
int _peu_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
int default_granularity
Definition: papi.h:642
#define PAPI_ENOSUPP
Definition: papi.h:269
#define PAPI_DATA_ADDRESS
Definition: papi.h:450
#define PAPI_DOM_KERNEL
Definition: papi.h:298
papi_vector_t _perf_event_uncore_vector
EventSetInfo_t * ESI
#define PAPI_DOM_ALL
Definition: papi.h:301
#define PERF_EVENTS_OPENED
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
static int close_pe_events(pe_context_t *ctx, pe_control_t *ctl)
#define PAPI_EBUG
Definition: papi.h:257
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
fclose(thread_wqfd)
#define PAPI_DOM_USER
Definition: papi.h:296
int _peu_libpfm4_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)
void
Definition: iozone.c:18627
int _peu_libpfm4_ntv_enum_events(unsigned int *PapiEventCode, int modifier, struct native_event_table_t *event_table)
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
#define PAPI_EPERM
Definition: papi.h:266
papi_vector_t * _papi_hwd[]
int _peu_libpfm4_init(papi_vector_t *my_vector, struct native_event_table_t *event_table, int pmu_type)
int _peu_ntv_enum_events(unsigned int *PapiEventCode, int modifier)
#define PAPI_INHERIT
Definition: papi.h:456
Return codes and api definitions.
uint32_t nr_mmap_pages
FILE * fff[MAX_EVENTS]
static int check_scheduability(pe_context_t *ctx, pe_control_t *ctl)
unsigned int domain
char events[MAX_EVENTS][BUFSIZ]
int multiplex(void)
Definition: multiplex.c:35
_papi_int_attach_t attach
long long ret
Definition: iozone.c:1346
unsigned long tid
_papi_int_cpu_t cpu
int i
Definition: fileop.c:140
int _papi_libpfm4_shutdown(void)
PAPI_os_info_t _papi_os_info
Definition: aix.c:1210
struct native_event_table_t uncore_native_event_table
static int pid
int _peu_libpfm4_ntv_name_to_code(char *name, unsigned int *event_code, struct native_event_table_t *event_table)
static int cidx
Definition: event_info.c:40
int _peu_libpfm4_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len, struct native_event_table_t *event_table)
#define PAPI_ESYS
Definition: papi.h:253
static int native
Definition: event_info.c:39
#define PAPI_GRANUL
Definition: papi.h:433
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
_papi_int_granularity_t granularity
int _peu_shutdown_thread(hwd_context_t *ctx)
#define PAPI_ECNFLCT
Definition: papi.h:259
EventSetInfo_t * ESI
#define PAPI_DETACH
Definition: papi.h:427
int _peu_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
void PAPIERROR(char *format,...)
unsigned int multiplexed
#define PAPI_ATTACH
Definition: papi.h:445
int _peu_init_control_state(hwd_control_state_t *ctl)
#define PAPI_ECMP
Definition: papi.h:254
struct native_event_table_t * event_table
int _peu_init_component(int cidx)
#define PAPI_MULTIPLEX
Definition: papi.h:429
#define PAPI_GRN_THR
Definition: papi.h:360
EventSetInfo_t * ESI
#define PAPI_GRN_SYS_CPU
Definition: papi.h:365
_papi_int_multiplex_t multiplex
#define PERF_EVENTS_RUNNING
#define PAPI_ENOMEM
Definition: papi.h:252
int _peu_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
again struct sockaddr sizeof(struct sockaddr_in))
#define PAPI_ENOCMP
Definition: papi.h:268
#define PAPI_DOMAIN
Definition: papi.h:431
int _peu_init_thread(hwd_context_t *hwd_ctx)
int _peu_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
#define LINUX_VERSION(a, b, c)
Definition: linux-common.h:4
int _peu_libpfm4_get_cidx()
unsigned int cpu_num
#define PMU_TYPE_UNCORE
#define PAPI_DEF_ITIMER
Definition: papi.h:452
char * name
Definition: iozone.c:23648
perf_event_attr_t attr
static int _peu_set_domain(hwd_control_state_t *ctl, int domain)
struct perf_event_attr attr
int
Definition: iozone.c:18528
int _peu_libpfm4_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len, struct native_event_table_t *event_table)
static unsigned int get_read_format(unsigned int multiplex, unsigned int inherit, int format_group)
int _peu_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
unsigned int inherit
#define PAPI_MAX_STR_LEN
Definition: papi.h:463
_papi_int_domain_t domain
static long sys_perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
#define PAPI_GRN_PROCG
Definition: papi.h:363
int _peu_libpfm4_shutdown(papi_vector_t *my_vector, struct native_event_table_t *event_table)
int _peu_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len)
#define READ_BUFFER_SIZE
#define PAPI_DOM_SUPERVISOR
Definition: papi.h:300
EventSetInfo_t * ESI
#define PAPI_GRN_SYS
Definition: papi.h:364
hwd_control_state_t * ctl_state
int _peu_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
long j
Definition: iozone.c:19135
ssize_t retval
Definition: libasync.c:338
#define PAPI_GRN_PROC
Definition: papi.h:362