PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
perf_event_uncore.c File Reference
Include dependency graph for perf_event_uncore.c:

Go to the source code of this file.

Macros

#define PERF_EVENTS_OPENED   0x01
 
#define PERF_EVENTS_RUNNING   0x02
 
#define READ_BUFFER_SIZE   (3 + (2 * PERF_EVENT_MAX_MPX_COUNTERS))
 

Functions

int _peu_libpfm4_get_cidx ()
 
static int _peu_set_domain (hwd_control_state_t *ctl, int domain)
 
static int bug_check_scheduability (void)
 
static unsigned int get_read_format (unsigned int multiplex, unsigned int inherit, int format_group)
 
static long sys_perf_event_open (struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
 
static int map_perf_event_errors_to_papi (int perf_event_error)
 
static int check_scheduability (pe_context_t *ctx, pe_control_t *ctl)
 
static int open_pe_events (pe_context_t *ctx, pe_control_t *ctl)
 
static int close_pe_events (pe_context_t *ctx, pe_control_t *ctl)
 
int _peu_init_thread (hwd_context_t *hwd_ctx)
 
int _peu_init_control_state (hwd_control_state_t *ctl)
 
int _peu_init_component (int cidx)
 
int _peu_shutdown_component (void)
 
int _peu_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
 
int _peu_shutdown_thread (hwd_context_t *ctx)
 
int _peu_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
int _peu_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
 
int _peu_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
 
int _peu_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
int _peu_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
int _peu_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
int _peu_ntv_enum_events (unsigned int *PapiEventCode, int modifier)
 
int _peu_ntv_name_to_code (char *name, unsigned int *event_code)
 
int _peu_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
 
int _peu_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len)
 
int _peu_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info)
 

Variables

papi_vector_t _perf_event_uncore_vector
 
struct native_event_table_t uncore_native_event_table
 
static int our_cidx
 

Macro Definition Documentation

#define PERF_EVENTS_OPENED   0x01

Definition at line 59 of file perf_event_uncore.c.

#define PERF_EVENTS_RUNNING   0x02

Definition at line 60 of file perf_event_uncore.c.

#define READ_BUFFER_SIZE   (3 + (2 * PERF_EVENT_MAX_MPX_COUNTERS))

Definition at line 243 of file perf_event_uncore.c.

Function Documentation

int _peu_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

Definition at line 1150 of file perf_event_uncore.c.

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 }
_papi_int_inherit_t inherit
#define PAPI_CPU_ATTACH
Definition: papi.h:455
EventSetInfo_t * ESI
unsigned int granularity
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:453
EventSetInfo_t * ESI
#define PAPI_INSTR_ADDRESS
Definition: papi.h:451
#define PAPI_DEF_MPX_NS
Definition: papi.h:434
#define PAPI_ENOSUPP
Definition: papi.h:269
#define PAPI_DATA_ADDRESS
Definition: papi.h:450
EventSetInfo_t * ESI
return PAPI_OK
Definition: linux-nvml.c:458
return PAPI_EINVAL
Definition: linux-nvml.c:408
#define PAPI_INHERIT
Definition: papi.h:456
unsigned int domain
_papi_int_attach_t attach
long long ret
Definition: iozone.c:1346
unsigned long tid
_papi_int_cpu_t cpu
#define PAPI_GRANUL
Definition: papi.h:433
_papi_int_granularity_t granularity
EventSetInfo_t * ESI
#define PAPI_DETACH
Definition: papi.h:427
unsigned int multiplexed
#define PAPI_ATTACH
Definition: papi.h:445
#define PAPI_ECMP
Definition: papi.h:254
#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 PAPI_DOMAIN
Definition: papi.h:431
unsigned int cpu_num
#define PAPI_DEF_ITIMER
Definition: papi.h:452
unsigned int inherit
_papi_int_domain_t domain
#define PAPI_GRN_PROCG
Definition: papi.h:363
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)
#define PAPI_GRN_PROC
Definition: papi.h:362

Here is the call graph for this function:

int _peu_init_component ( int  cidx)

Definition at line 617 of file perf_event_uncore.c.

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 }
static int our_cidx
int _papi_libpfm4_init(papi_vector_t *my_vector)
return PAPI_OK
Definition: linux-nvml.c:458
fclose(thread_wqfd)
papi_vector_t * _papi_hwd[]
int _peu_libpfm4_init(papi_vector_t *my_vector, struct native_event_table_t *event_table, int pmu_type)
FILE * fff[MAX_EVENTS]
struct native_event_table_t uncore_native_event_table
static int cidx
Definition: event_info.c:40
#define PAPI_ENOCMP
Definition: papi.h:268
#define PMU_TYPE_UNCORE
#define PAPI_MAX_STR_LEN
Definition: papi.h:463
ssize_t retval
Definition: libasync.c:338

Here is the call graph for this function:

int _peu_init_control_state ( hwd_control_state_t ctl)

Definition at line 592 of file perf_event_uncore.c.

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 */
601 
602  /* Set the 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 }
static int our_cidx
memset(eventId, 0, size)
unsigned int granularity
int default_granularity
Definition: papi.h:642
papi_vector_t _perf_event_uncore_vector
return PAPI_OK
Definition: linux-nvml.c:458
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
static int _peu_set_domain(hwd_control_state_t *ctl, int domain)

Here is the call graph for this function:

int _peu_init_thread ( hwd_context_t hwd_ctx)

Definition at line 575 of file perf_event_uncore.c.

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 }
static int our_cidx
memset(eventId, 0, size)
return PAPI_OK
Definition: linux-nvml.c:458
struct native_event_table_t uncore_native_event_table
struct native_event_table_t * event_table

Here is the call graph for this function:

int _peu_libpfm4_get_cidx ( void  )

Definition at line 54 of file perf_event_uncore.c.

54  {
55  return our_cidx;
56 }
static int our_cidx

Here is the caller graph for this function:

int _peu_ntv_code_to_descr ( unsigned int  EventCode,
char *  ntv_descr,
int  len 
)

Definition at line 1296 of file perf_event_uncore.c.

1297  {
1298 
1300 
1301  return _peu_libpfm4_ntv_code_to_descr(EventCode,ntv_descr,len,
1303 }
#define PAPI_ENOEVNT
Definition: papi.h:258
papi_vector_t _perf_event_uncore_vector
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
struct native_event_table_t uncore_native_event_table
int _peu_libpfm4_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len, struct native_event_table_t *event_table)

Here is the call graph for this function:

int _peu_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)

Definition at line 1306 of file perf_event_uncore.c.

1307  {
1308 
1310 
1311  return _peu_libpfm4_ntv_code_to_info(EventCode, info,
1313 }
#define PAPI_ENOEVNT
Definition: papi.h:258
papi_vector_t _perf_event_uncore_vector
int _peu_libpfm4_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
struct native_event_table_t uncore_native_event_table

Here is the call graph for this function:

int _peu_ntv_code_to_name ( unsigned int  EventCode,
char *  ntv_name,
int  len 
)

Definition at line 1285 of file perf_event_uncore.c.

1286  {
1287 
1289 
1290  return _peu_libpfm4_ntv_code_to_name(EventCode,
1291  ntv_name, len,
1293 }
#define PAPI_ENOEVNT
Definition: papi.h:258
papi_vector_t _perf_event_uncore_vector
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
struct native_event_table_t uncore_native_event_table
int _peu_libpfm4_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len, struct native_event_table_t *event_table)

Here is the call graph for this function:

int _peu_ntv_enum_events ( unsigned int PapiEventCode,
int  modifier 
)

Definition at line 1265 of file perf_event_uncore.c.

1266 {
1267 
1269 
1270 
1271  return _peu_libpfm4_ntv_enum_events(PapiEventCode, modifier,
1273 }
#define PAPI_ENOEVNT
Definition: papi.h:258
papi_vector_t _perf_event_uncore_vector
int _peu_libpfm4_ntv_enum_events(unsigned int *PapiEventCode, int modifier, struct native_event_table_t *event_table)
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
struct native_event_table_t uncore_native_event_table

Here is the call graph for this function:

int _peu_ntv_name_to_code ( char *  name,
unsigned int event_code 
)

Definition at line 1276 of file perf_event_uncore.c.

1276  {
1277 
1279 
1280  return _peu_libpfm4_ntv_name_to_code(name,event_code,
1282 }
#define PAPI_ENOEVNT
Definition: papi.h:258
papi_vector_t _perf_event_uncore_vector
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
struct native_event_table_t uncore_native_event_table
int _peu_libpfm4_ntv_name_to_code(char *name, unsigned int *event_code, struct native_event_table_t *event_table)
char * name
Definition: iozone.c:23648

Here is the call graph for this function:

int _peu_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)

Definition at line 914 of file perf_event_uncore.c.

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 }
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:225
long long counts[PERF_EVENT_MAX_MPX_COUNTERS]
int errno
long long flags
Definition: iozone.c:12330
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
return PAPI_OK
Definition: linux-nvml.c:458
void
Definition: iozone.c:18627
char events[MAX_EVENTS][BUFSIZ]
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:253
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
void PAPIERROR(char *format,...)
unsigned int multiplexed
again struct sockaddr sizeof(struct sockaddr_in))
unsigned int inherit
#define READ_BUFFER_SIZE
long j
Definition: iozone.c:19135

Here is the call graph for this function:

int _peu_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 859 of file perf_event_uncore.c.

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 }
int errno
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
return PAPI_OK
Definition: linux-nvml.c:458
void
Definition: iozone.c:18627
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:253
void PAPIERROR(char *format,...)

Here is the call graph for this function:

Here is the caller graph for this function:

static int _peu_set_domain ( hwd_control_state_t ctl,
int  domain 
)
static

Definition at line 832 of file perf_event_uncore.c.

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 }
return PAPI_OK
Definition: linux-nvml.c:458
unsigned int domain
#define SUBDBG(format, args...)
Definition: papi_debug.h:63

Here is the caller graph for this function:

int _peu_shutdown_component ( void  )

Definition at line 690 of file perf_event_uncore.c.

690  {
691 
692  /* deallocate our event table */
694 
695  /* Shutdown libpfm4 */
697 
698  return PAPI_OK;
699 }
papi_vector_t _perf_event_uncore_vector
return PAPI_OK
Definition: linux-nvml.c:458
int _papi_libpfm4_shutdown(void)
struct native_event_table_t uncore_native_event_table
int _peu_libpfm4_shutdown(papi_vector_t *my_vector, struct native_event_table_t *event_table)

Here is the call graph for this function:

int _peu_shutdown_thread ( hwd_context_t ctx)

Definition at line 845 of file perf_event_uncore.c.

846 {
847  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
848 
849  pe_ctx->initialized=0;
850 
851  return PAPI_OK;
852 }
return PAPI_OK
Definition: linux-nvml.c:458
int _peu_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 1078 of file perf_event_uncore.c.

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 }
int _peu_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
#define PAPI_EBUG
Definition: papi.h:257
return PAPI_OK
Definition: linux-nvml.c:458
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:253
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
void PAPIERROR(char *format,...)
#define PERF_EVENTS_RUNNING

Here is the call graph for this function:

int _peu_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 1122 of file perf_event_uncore.c.

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 }
int errno
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
#define PAPI_EBUG
Definition: papi.h:257
return PAPI_OK
Definition: linux-nvml.c:458
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
void PAPIERROR(char *format,...)
#define PERF_EVENTS_RUNNING

Here is the call graph for this function:

int _peu_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Definition at line 706 of file perf_event_uncore.c.

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 }
#define PAPI_ENOEVNT
Definition: papi.h:258
static int open_pe_events(pe_context_t *ctx, pe_control_t *ctl)
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
struct native_event_t * native_events
#define PAPI_DOM_KERNEL
Definition: papi.h:298
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
static int close_pe_events(pe_context_t *ctx, pe_control_t *ctl)
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
#define PAPI_DOM_USER
Definition: papi.h:296
unsigned int domain
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
struct native_event_table_t * event_table
perf_event_attr_t attr
struct perf_event_attr attr
unsigned int inherit
long j
Definition: iozone.c:19135

Here is the call graph for this function:

Here is the caller graph for this function:

int _peu_write ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long from 
)

Definition at line 884 of file perf_event_uncore.c.

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 }
#define PAPI_ENOSUPP
Definition: papi.h:269
void
Definition: iozone.c:18627
static int bug_check_scheduability ( void  )
static

Definition at line 82 of file perf_event_uncore.c.

82  {
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 }
PAPI_os_info_t _papi_os_info
Definition: aix.c:1210
#define LINUX_VERSION(a, b, c)
Definition: linux-common.h:4

Here is the caller graph for this function:

static int check_scheduability ( pe_context_t ctx,
pe_control_t ctl 
)
static

Definition at line 253 of file perf_event_uncore.c.

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 }
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:225
static int bug_check_scheduability(void)
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
return PAPI_OK
Definition: linux-nvml.c:458
void
Definition: iozone.c:18627
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:253
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PAPI_ECNFLCT
Definition: papi.h:259
#define READ_BUFFER_SIZE
ssize_t retval
Definition: libasync.c:338

Here is the call graph for this function:

Here is the caller graph for this function:

static int close_pe_events ( pe_context_t ctx,
pe_control_t ctl 
)
static

Definition at line 478 of file perf_event_uncore.c.

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 }
int errno
int close(int fd)
Definition: appio.c:175
#define PERF_EVENTS_OPENED
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
#define PAPI_EBUG
Definition: papi.h:257
return PAPI_OK
Definition: linux-nvml.c:458
uint32_t nr_mmap_pages
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:253
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
void PAPIERROR(char *format,...)
#define PERF_EVENTS_RUNNING

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int get_read_format ( unsigned int  multiplex,
unsigned int  inherit,
int  format_group 
)
static

Definition at line 102 of file perf_event_uncore.c.

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 }
i inherit inherit
int multiplex(void)
Definition: multiplex.c:35
#define SUBDBG(format, args...)
Definition: papi_debug.h:63

Here is the caller graph for this function:

static int map_perf_event_errors_to_papi ( int  perf_event_error)
static

Definition at line 202 of file perf_event_uncore.c.

202  {
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 }
#define PAPI_ENOEVNT
Definition: papi.h:258
#define PAPI_ENOSUPP
Definition: papi.h:269
return PAPI_EINVAL
Definition: linux-nvml.c:408
#define PAPI_EPERM
Definition: papi.h:266
long long ret
Definition: iozone.c:1346
#define PAPI_ESYS
Definition: papi.h:253
#define PAPI_ENOMEM
Definition: papi.h:252

Here is the caller graph for this function:

static int open_pe_events ( pe_context_t ctx,
pe_control_t ctl 
)
static

Definition at line 331 of file perf_event_uncore.c.

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 }
int errno
int close(int fd)
Definition: appio.c:175
unsigned int granularity
static int map_perf_event_errors_to_papi(int perf_event_error)
#define PERF_EVENTS_OPENED
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
return PAPI_OK
Definition: linux-nvml.c:458
static int check_scheduability(pe_context_t *ctx, pe_control_t *ctl)
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
static int pid
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
unsigned int multiplexed
struct perf_event_attr attr
static unsigned int get_read_format(unsigned int multiplex, unsigned int inherit, int format_group)
unsigned int inherit
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_SYS
Definition: papi.h:364

Here is the call graph for this function:

Here is the caller graph for this function:

static long sys_perf_event_open ( struct perf_event_attr hw_event,
pid_t  pid,
int  cpu,
int  group_fd,
unsigned long  flags 
)
static

Definition at line 151 of file perf_event_uncore.c.

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 }
int errno
long long flags
Definition: iozone.c:12330
cpu
Definition: iozone.c:3872
long long ret
Definition: iozone.c:1346
static int pid
#define SUBDBG(format, args...)
Definition: papi_debug.h:63

Here is the caller graph for this function:

Variable Documentation

papi_vector_t _perf_event_uncore_vector

Definition at line 48 of file perf_event_uncore.c.

int our_cidx
static

Definition at line 52 of file perf_event_uncore.c.

struct native_event_table_t uncore_native_event_table

Definition at line 51 of file perf_event_uncore.c.