PAPI  5.6.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

static int _peu_set_domain (hwd_control_state_t *ctl, int domain)
 
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)
 
static int _peu_init_thread (hwd_context_t *hwd_ctx)
 
static int _peu_init_control_state (hwd_control_state_t *ctl)
 
static int _peu_init_component (int cidx)
 
static int _peu_shutdown_component (void)
 
int _peu_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
 
static int _peu_shutdown_thread (hwd_context_t *ctx)
 
static int _peu_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _peu_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
 
static int _peu_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
 
static int _peu_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _peu_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _peu_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
static int _peu_ntv_enum_events (unsigned int *PapiEventCode, int modifier)
 
static int _peu_ntv_name_to_code (const char *name, unsigned int *event_code)
 
static int _peu_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
 
static int _peu_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len)
 
static 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 60 of file perf_event_uncore.c.

#define PERF_EVENTS_RUNNING   0x02

Definition at line 61 of file perf_event_uncore.c.

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

Definition at line 216 of file perf_event_uncore.c.

Function Documentation

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

Definition at line 1122 of file perf_event_uncore.c.

1123 {
1124  int ret;
1125  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
1126  pe_control_t *pe_ctl = NULL;
1127 
1128  switch ( code ) {
1129  case PAPI_MULTIPLEX:
1130  pe_ctl = ( pe_control_t * ) ( option->multiplex.ESI->ctl_state );
1131 
1132  pe_ctl->multiplexed = 1;
1133  ret = _peu_update_control_state( pe_ctl, NULL,
1134  pe_ctl->num_events, pe_ctx );
1135  if (ret != PAPI_OK) {
1136  pe_ctl->multiplexed = 0;
1137  }
1138  return ret;
1139 
1140  case PAPI_ATTACH:
1141  pe_ctl = ( pe_control_t * ) ( option->attach.ESI->ctl_state );
1142 
1143  pe_ctl->tid = option->attach.tid;
1144 
1145  /* If events have been already been added, something may */
1146  /* have been done to the kernel, so update */
1147  ret =_peu_update_control_state( pe_ctl, NULL,
1148  pe_ctl->num_events, pe_ctx);
1149 
1150  return ret;
1151 
1152  case PAPI_DETACH:
1153  pe_ctl = ( pe_control_t *) ( option->attach.ESI->ctl_state );
1154 
1155  pe_ctl->tid = 0;
1156  return PAPI_OK;
1157 
1158  case PAPI_CPU_ATTACH:
1159  pe_ctl = ( pe_control_t *) ( option->cpu.ESI->ctl_state );
1160 
1161  /* this tells the kernel not to count for a thread */
1162  /* should we warn if we try to set both? perf_event */
1163  /* will reject it. */
1164  pe_ctl->tid = -1;
1165 
1166  pe_ctl->cpu = option->cpu.cpu_num;
1167 
1168  return PAPI_OK;
1169 
1170  case PAPI_DOMAIN:
1171  pe_ctl = ( pe_control_t *) ( option->domain.ESI->ctl_state );
1172 
1173  /* looks like we are allowed, so set event set level counting domains */
1174  pe_ctl->domain = option->domain.domain;
1175  return PAPI_OK;
1176 
1177  case PAPI_GRANUL:
1178  pe_ctl = (pe_control_t *) ( option->granularity.ESI->ctl_state );
1179 
1180  /* FIXME: we really don't support this yet */
1181 
1182  switch ( option->granularity.granularity ) {
1183  case PAPI_GRN_PROCG:
1184  case PAPI_GRN_SYS_CPU:
1185  case PAPI_GRN_PROC:
1186  return PAPI_ECMP;
1187 
1188  /* Currently we only support thread and CPU granularity */
1189  case PAPI_GRN_SYS:
1190  pe_ctl->granularity=PAPI_GRN_SYS;
1191  break;
1192 
1193  case PAPI_GRN_THR:
1194  pe_ctl->granularity=PAPI_GRN_THR;
1195  break;
1196 
1197 
1198  default:
1199  return PAPI_EINVAL;
1200  }
1201  return PAPI_OK;
1202 
1203  case PAPI_INHERIT:
1204  pe_ctl = (pe_control_t *) ( option->inherit.ESI->ctl_state );
1205 
1206  if (option->inherit.inherit) {
1207  /* children will inherit counters */
1208  pe_ctl->inherit = 1;
1209  } else {
1210  /* children won't inherit counters */
1211  pe_ctl->inherit = 0;
1212  }
1213  return PAPI_OK;
1214 
1215  case PAPI_DATA_ADDRESS:
1216  return PAPI_ENOSUPP;
1217 
1218  case PAPI_INSTR_ADDRESS:
1219  return PAPI_ENOSUPP;
1220 
1221  case PAPI_DEF_ITIMER:
1222  return PAPI_ENOSUPP;
1223 
1224  case PAPI_DEF_MPX_NS:
1225  return PAPI_ENOSUPP;
1226 
1227  case PAPI_DEF_ITIMER_NS:
1228  return PAPI_ENOSUPP;
1229 
1230  default:
1231  return PAPI_ENOSUPP;
1232  }
1233 }
_papi_int_inherit_t inherit
#define PAPI_CPU_ATTACH
Definition: papi.h:457
EventSetInfo_t * ESI
unsigned int granularity
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:455
EventSetInfo_t * ESI
#define PAPI_INSTR_ADDRESS
Definition: papi.h:453
#define PAPI_DEF_MPX_NS
Definition: papi.h:436
#define PAPI_ENOSUPP
Definition: papi.h:271
#define PAPI_DATA_ADDRESS
Definition: papi.h:452
EventSetInfo_t * ESI
return PAPI_OK
Definition: linux-nvml.c:497
return PAPI_EINVAL
Definition: linux-nvml.c:436
#define PAPI_INHERIT
Definition: papi.h:458
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:435
_papi_int_granularity_t granularity
EventSetInfo_t * ESI
#define PAPI_DETACH
Definition: papi.h:429
unsigned int multiplexed
#define PAPI_ATTACH
Definition: papi.h:447
#define PAPI_ECMP
Definition: papi.h:256
#define PAPI_MULTIPLEX
Definition: papi.h:431
#define PAPI_GRN_THR
Definition: papi.h:362
EventSetInfo_t * ESI
#define PAPI_GRN_SYS_CPU
Definition: papi.h:367
_papi_int_multiplex_t multiplex
#define PAPI_DOMAIN
Definition: papi.h:433
unsigned int cpu_num
#define PAPI_DEF_ITIMER
Definition: papi.h:454
unsigned int inherit
_papi_int_domain_t domain
#define PAPI_GRN_PROCG
Definition: papi.h:365
EventSetInfo_t * ESI
#define PAPI_GRN_SYS
Definition: papi.h:366
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:364

Here is the call graph for this function:

static int _peu_init_component ( int  cidx)
static

Definition at line 587 of file perf_event_uncore.c.

588 {
589 
590  int retval;
591  int paranoid_level;
592 
593  FILE *fff;
594 
595  our_cidx=cidx;
596 
597  /* The is the official way to detect if perf_event support exists */
598  /* The file is called perf_counter_paranoid on 2.6.31 */
599  /* currently we are lazy and do not support 2.6.31 kernels */
600 
601  fff=fopen("/proc/sys/kernel/perf_event_paranoid","r");
602  if (fff==NULL) {
603  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
604  "perf_event support not detected",PAPI_MAX_STR_LEN);
605  return PAPI_ENOCMP;
606  }
607  retval=fscanf(fff,"%d",&paranoid_level);
608  if (retval!=1) fprintf(stderr,"Error reading paranoid level\n");
609  fclose(fff);
610 
611 
612  /* Run the libpfm4-specific setup */
613 
614  retval = _papi_libpfm4_init(_papi_hwd[cidx]);
615  if (retval) {
616  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
617  "Error initializing libpfm4",PAPI_MAX_STR_LEN);
618  return PAPI_ENOCMP;
619  }
620 
621 
622  /* Run the uncore specific libpfm4 setup */
623 
627  if (retval) {
628  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
629  "Error setting up libpfm4",PAPI_MAX_STR_LEN);
630  return PAPI_ENOCMP;
631  }
632 
633  /* Check if no uncore events found */
634 
635  if (_papi_hwd[cidx]->cmp_info.num_native_events==0) {
636  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
637  "No uncore PMUs or events found",PAPI_MAX_STR_LEN);
638  return PAPI_ENOCMP;
639  }
640 
641  /* Check if we have enough permissions for uncore */
642 
643  /* 2 means no kernel measurements allowed */
644  /* 1 means normal counter access */
645  /* 0 means you can access CPU-specific data */
646  /* -1 means no restrictions */
647 
648  if ((paranoid_level>0) && (getuid()!=0)) {
649  strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
650  "Insufficient permissions for uncore access. Set /proc/sys/kernel/perf_event_paranoid to 0 or run as root.",
652  return PAPI_ENOCMP;
653  }
654 
655  return PAPI_OK;
656 
657 }
static int our_cidx
int _papi_libpfm4_init(papi_vector_t *my_vector)
return PAPI_OK
Definition: linux-nvml.c:497
fclose(thread_wqfd)
papi_vector_t * _papi_hwd[]
FILE * fff[MAX_EVENTS]
static int cidx
struct native_event_table_t uncore_native_event_table
int _peu_libpfm4_init(papi_vector_t *my_vector, int cidx, struct native_event_table_t *event_table, int pmu_type)
#define PAPI_ENOCMP
Definition: papi.h:270
#define PMU_TYPE_UNCORE
#define PAPI_MAX_STR_LEN
Definition: papi.h:465
ssize_t retval
Definition: libasync.c:338

Here is the call graph for this function:

static int _peu_init_control_state ( hwd_control_state_t ctl)
static

Definition at line 562 of file perf_event_uncore.c.

563 {
564  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
565 
566  /* clear the contents */
567  memset( pe_ctl, 0, sizeof ( pe_control_t ) );
568 
569  /* Set the default domain */
571 
572  /* Set the default granularity */
574 
575  pe_ctl->cidx=our_cidx;
576 
577  /* Set cpu number in the control block to show events */
578  /* are not tied to specific cpu */
579  pe_ctl->cpu = -1;
580  return PAPI_OK;
581 }
static int our_cidx
unsigned int granularity
int default_granularity
Definition: papi.h:645
papi_vector_t _perf_event_uncore_vector
return PAPI_OK
Definition: linux-nvml.c:497
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:

static int _peu_init_thread ( hwd_context_t hwd_ctx)
static

Definition at line 545 of file perf_event_uncore.c.

546 {
547 
548  pe_context_t *pe_ctx = ( pe_context_t *) hwd_ctx;
549 
550  /* clear the context structure and mark as initialized */
551  memset( pe_ctx, 0, sizeof ( pe_context_t ) );
552  pe_ctx->initialized=1;
553 
555  pe_ctx->cidx=our_cidx;
556 
557  return PAPI_OK;
558 }
static int our_cidx
return PAPI_OK
Definition: linux-nvml.c:497
struct native_event_table_t uncore_native_event_table
struct native_event_table_t * event_table
static int _peu_ntv_code_to_descr ( unsigned int  EventCode,
char *  ntv_descr,
int  len 
)
static

Definition at line 1268 of file perf_event_uncore.c.

1269  {
1270 
1272 
1273  return _pe_libpfm4_ntv_code_to_descr(EventCode,ntv_descr,len,
1275 }
#define PAPI_ENOEVNT
Definition: papi.h:260
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 _pe_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:

static int _peu_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)
static

Definition at line 1278 of file perf_event_uncore.c.

1279  {
1280 
1282 
1283  return _pe_libpfm4_ntv_code_to_info(EventCode, info,
1285 }
#define PAPI_ENOEVNT
Definition: papi.h:260
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 _pe_libpfm4_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)

Here is the call graph for this function:

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

Definition at line 1257 of file perf_event_uncore.c.

1258  {
1259 
1261 
1262  return _pe_libpfm4_ntv_code_to_name(EventCode,
1263  ntv_name, len,
1265 }
#define PAPI_ENOEVNT
Definition: papi.h:260
papi_vector_t _perf_event_uncore_vector
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
int _pe_libpfm4_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len, struct native_event_table_t *event_table)
struct native_event_table_t uncore_native_event_table

Here is the call graph for this function:

static int _peu_ntv_enum_events ( unsigned int PapiEventCode,
int  modifier 
)
static

Definition at line 1237 of file perf_event_uncore.c.

1238 {
1239 
1241 
1242 
1243  return _pe_libpfm4_ntv_enum_events(PapiEventCode, modifier, our_cidx,
1245 }
#define PAPI_ENOEVNT
Definition: papi.h:260
static int our_cidx
papi_vector_t _perf_event_uncore_vector
int _pe_libpfm4_ntv_enum_events(unsigned int *PapiEventCode, int modifier, int cidx, 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:

static int _peu_ntv_name_to_code ( const char *  name,
unsigned int event_code 
)
static

Definition at line 1248 of file perf_event_uncore.c.

1248  {
1249 
1251 
1252  return _pe_libpfm4_ntv_name_to_code(name,event_code, our_cidx,
1254 }
#define PAPI_ENOEVNT
Definition: papi.h:260
static int our_cidx
papi_vector_t _perf_event_uncore_vector
int _pe_libpfm4_ntv_name_to_code(const char *name, unsigned int *event_code, int cidx, 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
char * name
Definition: iozone.c:23648

Here is the call graph for this function:

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

Definition at line 886 of file perf_event_uncore.c.

888 {
889  SUBDBG("ENTER: ctx: %p, ctl: %p, events: %p, flags: %#x\n", ctx, ctl, events, flags);
890 
891  ( void ) flags; /*unused */
892  int i, ret = -1;
893  /* pe_context_t *pe_ctx = ( pe_context_t *) ctx; */
894  (void) ctx; /*unused*/
895  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
896  long long papi_pe_buffer[READ_BUFFER_SIZE];
897  long long tot_time_running, tot_time_enabled, scale;
898 
899  /* Handle case where we are multiplexing */
900  if (pe_ctl->multiplexed) {
901 
902  /* currently we handle multiplexing by having individual events */
903  /* so we read from each in turn. */
904 
905  for ( i = 0; i < pe_ctl->num_events; i++ ) {
906 
907  ret = read( pe_ctl->events[i].event_fd, papi_pe_buffer,
908  sizeof ( papi_pe_buffer ) );
909  if ( ret == -1 ) {
910  PAPIERROR("read returned an error: ", strerror( errno ));
911  SUBDBG("EXIT: PAPI_ESYS\n");
912  return PAPI_ESYS;
913  }
914 
915  /* We should read 3 64-bit values from the counter */
916  if (ret<(signed)(3*sizeof(long long))) {
917  PAPIERROR("Error! short read!\n");
918  SUBDBG("EXIT: PAPI_ESYS\n");
919  return PAPI_ESYS;
920  }
921 
922  SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
923  pe_ctl->events[i].event_fd,
924  (long)pe_ctl->tid, pe_ctl->events[i].cpu, ret);
925  SUBDBG("read: %lld %lld %lld\n",papi_pe_buffer[0],
926  papi_pe_buffer[1],papi_pe_buffer[2]);
927 
928  tot_time_enabled = papi_pe_buffer[1];
929  tot_time_running = papi_pe_buffer[2];
930 
931  SUBDBG("count[%d] = (papi_pe_buffer[%d] %lld * "
932  "tot_time_enabled %lld) / tot_time_running %lld\n",
933  i, 0,papi_pe_buffer[0],
934  tot_time_enabled,tot_time_running);
935 
936  if (tot_time_running == tot_time_enabled) {
937  /* No scaling needed */
938  pe_ctl->counts[i] = papi_pe_buffer[0];
939  } else if (tot_time_running && tot_time_enabled) {
940  /* Scale factor of 100 to avoid overflows when computing */
941  /*enabled/running */
942 
943  scale = (tot_time_enabled * 100LL) / tot_time_running;
944  scale = scale * papi_pe_buffer[0];
945  scale = scale / 100LL;
946  pe_ctl->counts[i] = scale;
947  } else {
948  /* This should not happen, but Phil reports it sometime does. */
949  SUBDBG("perf_event kernel bug(?) count, enabled, "
950  "running: %lld, %lld, %lld\n",
951  papi_pe_buffer[0],tot_time_enabled,
952  tot_time_running);
953 
954  pe_ctl->counts[i] = papi_pe_buffer[0];
955  }
956  }
957  }
958 
959  /* Handle cases where we cannot use FORMAT GROUP */
960  else if (pe_ctl->inherit) {
961 
962  /* we must read each counter individually */
963  for ( i = 0; i < pe_ctl->num_events; i++ ) {
964 
965  ret = read( pe_ctl->events[i].event_fd, papi_pe_buffer,
966  sizeof ( papi_pe_buffer ) );
967  if ( ret == -1 ) {
968  PAPIERROR("read returned an error: ", strerror( errno ));
969  SUBDBG("EXIT: PAPI_ESYS\n");
970  return PAPI_ESYS;
971  }
972 
973  /* we should read one 64-bit value from each counter */
974  if (ret!=sizeof(long long)) {
975  PAPIERROR("Error! short read!\n");
976  PAPIERROR("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
977  pe_ctl->events[i].event_fd,
978  (long)pe_ctl->tid, pe_ctl->events[i].cpu, ret);
979  SUBDBG("EXIT: PAPI_ESYS\n");
980  return PAPI_ESYS;
981  }
982 
983  SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
984  pe_ctl->events[i].event_fd, (long)pe_ctl->tid,
985  pe_ctl->events[i].cpu, ret);
986  SUBDBG("read: %lld\n",papi_pe_buffer[0]);
987 
988  pe_ctl->counts[i] = papi_pe_buffer[0];
989  }
990  }
991 
992 
993  /* Handle cases where we are using FORMAT_GROUP */
994  /* We assume only one group leader, in position 0 */
995 
996  else {
997  if (pe_ctl->events[0].group_leader_fd!=-1) {
998  PAPIERROR("Was expecting group leader!\n");
999  }
1000 
1001  ret = read( pe_ctl->events[0].event_fd, papi_pe_buffer,
1002  sizeof ( papi_pe_buffer ) );
1003 
1004  if ( ret == -1 ) {
1005  PAPIERROR("read returned an error: ", strerror( errno ));
1006  SUBDBG("EXIT: PAPI_ESYS\n");
1007  return PAPI_ESYS;
1008  }
1009 
1010  /* we read 1 64-bit value (number of events) then */
1011  /* num_events more 64-bit values that hold the counts */
1012  if (ret<(signed)((1+pe_ctl->num_events)*sizeof(long long))) {
1013  PAPIERROR("Error! short read!\n");
1014  SUBDBG("EXIT: PAPI_ESYS\n");
1015  return PAPI_ESYS;
1016  }
1017 
1018  SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
1019  pe_ctl->events[0].event_fd,
1020  (long)pe_ctl->tid, pe_ctl->events[0].cpu, ret);
1021  {
1022  int j;
1023  for(j=0;j<ret/8;j++) {
1024  SUBDBG("read %d: %lld\n",j,papi_pe_buffer[j]);
1025  }
1026  }
1027 
1028  /* Make sure the kernel agrees with how many events we have */
1029  if (papi_pe_buffer[0]!=pe_ctl->num_events) {
1030  PAPIERROR("Error! Wrong number of events!\n");
1031  SUBDBG("EXIT: PAPI_ESYS\n");
1032  return PAPI_ESYS;
1033  }
1034 
1035  /* put the count values in their proper location */
1036  for(i=0;i<pe_ctl->num_events;i++) {
1037  pe_ctl->counts[i] = papi_pe_buffer[1+i];
1038  }
1039  }
1040 
1041  /* point PAPI to the values we read */
1042  *events = pe_ctl->counts;
1043 
1044  SUBDBG("EXIT: PAPI_OK\n");
1045  return PAPI_OK;
1046 }
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:497
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:255
#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:

static int _peu_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 831 of file perf_event_uncore.c.

832 {
833  int i, ret;
834  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
835 
836  ( void ) ctx; /*unused */
837 
838  /* We need to reset all of the events, not just the group leaders */
839  for( i = 0; i < pe_ctl->num_events; i++ ) {
840  ret = ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
841  if ( ret == -1 ) {
842  PAPIERROR("ioctl(%d, PERF_EVENT_IOC_RESET, NULL) "
843  "returned error, Linux says: %s",
844  pe_ctl->events[i].event_fd, strerror( errno ) );
845  return PAPI_ESYS;
846  }
847  }
848 
849  return PAPI_OK;
850 }
int errno
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
return PAPI_OK
Definition: linux-nvml.c:497
void
Definition: iozone.c:18627
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:255
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 804 of file perf_event_uncore.c.

805 {
806  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
807 
808  SUBDBG("old control domain %d, new domain %d\n",
809  pe_ctl->domain,domain);
810 
811  pe_ctl->domain = domain;
812  return PAPI_OK;
813 }
return PAPI_OK
Definition: linux-nvml.c:497
unsigned int domain
#define SUBDBG(format, args...)
Definition: papi_debug.h:63

Here is the caller graph for this function:

static int _peu_shutdown_component ( void  )
static

Definition at line 661 of file perf_event_uncore.c.

661  {
662 
663  /* deallocate our event table */
666 
667  /* Shutdown libpfm4 */
669 
670  return PAPI_OK;
671 }
papi_vector_t _perf_event_uncore_vector
return PAPI_OK
Definition: linux-nvml.c:497
struct native_event_table_t uncore_native_event_table
int _papi_libpfm4_shutdown(papi_vector_t *my_vector)
int _pe_libpfm4_shutdown(papi_vector_t *my_vector, struct native_event_table_t *event_table)

Here is the call graph for this function:

static int _peu_shutdown_thread ( hwd_context_t ctx)
static

Definition at line 817 of file perf_event_uncore.c.

818 {
819  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
820 
821  pe_ctx->initialized=0;
822 
823  return PAPI_OK;
824 }
return PAPI_OK
Definition: linux-nvml.c:497
static int _peu_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 1050 of file perf_event_uncore.c.

1051 {
1052  int ret;
1053  int i;
1054  int did_something = 0;
1055  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
1056  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
1057 
1058  /* Reset the counters first. Is this necessary? */
1059  ret = _peu_reset( pe_ctx, pe_ctl );
1060  if ( ret ) {
1061  return ret;
1062  }
1063 
1064  /* Enable all of the group leaders */
1065  /* All group leaders have a group_leader_fd of -1 */
1066  for( i = 0; i < pe_ctl->num_events; i++ ) {
1067  if (pe_ctl->events[i].group_leader_fd == -1) {
1068  SUBDBG("ioctl(enable): fd: %d\n", pe_ctl->events[i].event_fd);
1069  ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_ENABLE, NULL) ;
1070 
1071  /* ioctls always return -1 on failure */
1072  if (ret == -1) {
1073  PAPIERROR("ioctl(PERF_EVENT_IOC_ENABLE) failed.\n");
1074  return PAPI_ESYS;
1075  }
1076 
1077  did_something++;
1078  }
1079  }
1080 
1081  if (!did_something) {
1082  PAPIERROR("Did not enable any counters.\n");
1083  return PAPI_EBUG;
1084  }
1085 
1086  pe_ctx->state |= PERF_EVENTS_RUNNING;
1087 
1088  return PAPI_OK;
1089 
1090 }
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
#define PAPI_EBUG
Definition: papi.h:259
return PAPI_OK
Definition: linux-nvml.c:497
long long ret
Definition: iozone.c:1346
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:255
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
void PAPIERROR(char *format,...)
#define PERF_EVENTS_RUNNING
static int _peu_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)

Here is the call graph for this function:

static int _peu_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 1094 of file perf_event_uncore.c.

1095 {
1096 
1097  int ret;
1098  int i;
1099  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
1100  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
1101 
1102  /* Just disable the group leaders */
1103  for ( i = 0; i < pe_ctl->num_events; i++ ) {
1104  if ( pe_ctl->events[i].group_leader_fd == -1 ) {
1105  ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_DISABLE, NULL);
1106  if ( ret == -1 ) {
1107  PAPIERROR( "ioctl(%d, PERF_EVENT_IOC_DISABLE, NULL) "
1108  "returned error, Linux says: %s",
1109  pe_ctl->events[i].event_fd, strerror( errno ) );
1110  return PAPI_EBUG;
1111  }
1112  }
1113  }
1114 
1115  pe_ctx->state &= ~PERF_EVENTS_RUNNING;
1116 
1117  return PAPI_OK;
1118 }
int errno
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
#define PAPI_EBUG
Definition: papi.h:259
return PAPI_OK
Definition: linux-nvml.c:497
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 678 of file perf_event_uncore.c.

681 {
682  int i;
683  int j;
684  int ret;
685  int skipped_events=0;
686  struct native_event_t *ntv_evt;
687  pe_context_t *pe_ctx = ( pe_context_t *) ctx;
688  pe_control_t *pe_ctl = ( pe_control_t *) ctl;
689 
690  /* close all of the existing fds and start over again */
691  /* In theory we could have finer-grained control and know if */
692  /* things were changed, but it's easier to tear things down and rebuild. */
693  close_pe_events( pe_ctx, pe_ctl );
694 
695  /* Calling with count==0 should be OK, it's how things are deallocated */
696  /* when an eventset is destroyed. */
697  if ( count == 0 ) {
698  SUBDBG( "Called with count == 0\n" );
699  return PAPI_OK;
700  }
701 
702  /* set up all the events */
703  for( i = 0; i < count; i++ ) {
704  if ( native ) {
705  // get the native event pointer used for this papi event
706  int ntv_idx = _papi_hwi_get_ntv_idx((unsigned)(native[i].ni_papi_code));
707  if (ntv_idx < -1) {
708  SUBDBG("papi_event_code: %#x known by papi but not by the component\n", native[i].ni_papi_code);
709  continue;
710  }
711  // if native index is -1, then we have an event without a mask and need to find the right native index to use
712  if (ntv_idx == -1) {
713  // find the native event index we want by matching for the right papi event code
714  for (j=0 ; j<pe_ctx->event_table->num_native_events ; j++) {
715  if (pe_ctx->event_table->native_events[j].papi_event_code == native[i].ni_papi_code) {
716  ntv_idx = j;
717  }
718  }
719  }
720 
721  // if native index is still negative, we did not find event we wanted so just return error
722  if (ntv_idx < 0) {
723  SUBDBG("papi_event_code: %#x not found in native event tables\n", native[i].ni_papi_code);
724  continue;
725  }
726 
727  // this native index is positive so there was a mask with the event, the ntv_idx identifies which native event to use
728  ntv_evt = (struct native_event_t *)(&(pe_ctx->event_table->native_events[ntv_idx]));
729 
730  SUBDBG("ntv_evt: %p\n", ntv_evt);
731 
732  SUBDBG("i: %d, pe_ctx->event_table->num_native_events: %d\n", i, pe_ctx->event_table->num_native_events);
733 
734  // Move this events hardware config values and other attributes to the perf_events attribute structure
735  memcpy (&pe_ctl->events[i].attr, &ntv_evt->attr, sizeof(perf_event_attr_t));
736 
737  // may need to update the attribute structure with information from event set level domain settings (values set by PAPI_set_domain)
738  // only done if the event mask which controls each counting domain was not provided
739 
740  // get pointer to allocated name, will be NULL when adding preset events to event set
741  char *aName = ntv_evt->allocated_name;
742  if ((aName == NULL) || (strstr(aName, ":u=") == NULL)) {
743  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));
744  pe_ctl->events[i].attr.exclude_user = !(pe_ctl->domain & PAPI_DOM_USER);
745  }
746  if ((aName == NULL) || (strstr(aName, ":k=") == NULL)) {
747  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));
748  pe_ctl->events[i].attr.exclude_kernel = !(pe_ctl->domain & PAPI_DOM_KERNEL);
749  }
750 
751  // set the cpu number provided with an event mask if there was one (will be -1 if mask not provided)
752  pe_ctl->events[i].cpu = ntv_evt->cpu;
753  // 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)
754  if (pe_ctl->events[i].cpu == -1) {
755  pe_ctl->events[i].cpu = pe_ctl->cpu;
756  }
757  } else {
758  // This case happens when called from _pe_set_overflow and _pe_ctl
759  // Those callers put things directly into the pe_ctl structure so it is already set for the open call
760  }
761 
762  // Copy the inherit flag into the attribute block that will be passed to the kernel
763  pe_ctl->events[i].attr.inherit = pe_ctl->inherit;
764 
765  /* Set the position in the native structure */
766  /* We just set up events linearly */
767  if ( native ) {
768  native[i].ni_position = i;
769  SUBDBG( "&native[%d]: %p, ni_papi_code: %#x, ni_event: %#x, ni_position: %d, ni_owners: %d\n",
770  i, &(native[i]), native[i].ni_papi_code, native[i].ni_event, native[i].ni_position, native[i].ni_owners);
771  }
772  }
773 
774  if (count <= skipped_events) {
775  SUBDBG("EXIT: No events to count, they all contained invalid umasks\n");
776  return PAPI_ENOEVNT;
777  }
778 
779  pe_ctl->num_events = count - skipped_events;
780 
781  /* actuall open the events */
782  /* (why is this a separate function?) */
783  ret = open_pe_events( pe_ctx, pe_ctl );
784  if ( ret != PAPI_OK ) {
785  SUBDBG("open_pe_events failed\n");
786  /* Restore values ? */
787  return ret;
788  }
789 
790  SUBDBG( "EXIT: PAPI_OK\n" );
791  return PAPI_OK;
792 }
#define PAPI_ENOEVNT
Definition: papi.h:260
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:300
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:497
int count
Definition: iozone.c:22422
#define PAPI_DOM_USER
Definition: papi.h:298
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:

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

Definition at line 856 of file perf_event_uncore.c.

858 {
859  ( void ) ctx; /*unused */
860  ( void ) ctl; /*unused */
861  ( void ) from; /*unused */
862  /*
863  * Counters cannot be written. Do we need to virtualize the
864  * counters so that they can be written, or perhaps modify code so that
865  * they can be written? FIXME ?
866  */
867 
868  return PAPI_ENOSUPP;
869 }
#define PAPI_ENOSUPP
Definition: papi.h:271
void
Definition: iozone.c:18627
static int check_scheduability ( pe_context_t ctx,
pe_control_t ctl 
)
static

Definition at line 226 of file perf_event_uncore.c.

227 {
228  SUBDBG("ENTER: ctx: %p, ctl: %p\n", ctx, ctl);
229  int retval = 0, cnt = -1;
230  ( void ) ctx; /*unused */
231  long long papi_pe_buffer[READ_BUFFER_SIZE];
232  int i;
233 
234  /* If the kernel isn't tracking scheduability right */
235  /* Then we need to start/stop/read to force the event */
236  /* to be scheduled and see if an error condition happens. */
237 
238  /* start all events */
239  for( i = 0; i < ctl->num_events; i++) {
240  retval = ioctl( ctl->events[i].event_fd, PERF_EVENT_IOC_ENABLE, NULL );
241  if (retval == -1) {
242  SUBDBG("EXIT: Enable failed event index: %d, num_events: %d, return PAPI_ESYS\n", i, ctl->num_events);
243  return PAPI_ESYS;
244  }
245  }
246 
247  /* stop all events */
248  for( i = 0; i < ctl->num_events; i++) {
249  retval = ioctl(ctl->events[i].event_fd, PERF_EVENT_IOC_DISABLE, NULL );
250  if (retval == -1) {
251  SUBDBG("EXIT: Disable failed: event index: %d, num_events: %d, return PAPI_ESYS\n", i, ctl->num_events);
252  return PAPI_ESYS;
253  }
254  }
255 
256  /* See if a read of each event returns results */
257  for( i = 0; i < ctl->num_events; i++) {
258  cnt = read( ctl->events[i].event_fd, papi_pe_buffer, sizeof(papi_pe_buffer));
259  if ( cnt == -1 ) {
260  SUBDBG( "EXIT: read failed: event index: %d, num_events: %d, return PAPI_ESYS. Should never happen.\n", i, ctl->num_events);
261  return PAPI_ESYS;
262  }
263 
264  if ( cnt == 0 ) {
265  /* We read 0 bytes if we could not schedule the event */
266  /* The kernel should have detected this at open */
267  /* but various bugs (including NMI watchdog) */
268  /* result in this behavior */
269 
270  SUBDBG( "EXIT: read returned 0: event index: %d, num_events: %d, return PAPI_ECNFLCT.\n", i, ctl->num_events);
271  return PAPI_ECNFLCT;
272  }
273  }
274 
275  /* Reset all of the counters (opened so far) back to zero */
276  /* from the above brief enable/disable call pair. */
277 
278  /* We have to reset all events because reset of group leader */
279  /* does not reset all. */
280  /* we assume that the events are being added one by one and that */
281  /* we do not need to reset higher events (doing so may reset ones */
282  /* that have not been initialized yet. */
283 
284  /* Note... PERF_EVENT_IOC_RESET does not reset time running */
285  /* info if multiplexing, so we should avoid coming here if */
286  /* we are multiplexing the event. */
287  for( i = 0; i < ctl->num_events; i++) {
288  retval=ioctl( ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
289  if (retval == -1) {
290  SUBDBG("EXIT: Reset failed: event index: %d, num_events: %d, return PAPI_ESYS\n", i, ctl->num_events);
291  return PAPI_ESYS;
292  }
293  }
294  SUBDBG("EXIT: return PAPI_OK\n");
295  return PAPI_OK;
296 }
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:225
pe_event_info_t events[PERF_EVENT_MAX_MPX_COUNTERS]
return PAPI_OK
Definition: linux-nvml.c:497
void
Definition: iozone.c:18627
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:255
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PAPI_ECNFLCT
Definition: papi.h:261
#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 448 of file perf_event_uncore.c.

449 {
450  int i;
451  int num_closed=0;
452  int events_not_opened=0;
453 
454  /* should this be a more serious error? */
455  if ( ctx->state & PERF_EVENTS_RUNNING ) {
456  SUBDBG("Closing without stopping first\n");
457  }
458 
459  /* Close child events first */
460  for( i=0; i<ctl->num_events; i++ ) {
461 
462  if (ctl->events[i].event_opened) {
463 
464  if (ctl->events[i].group_leader_fd!=-1) {
465  if ( ctl->events[i].mmap_buf ) {
466  if ( munmap ( ctl->events[i].mmap_buf,
467  ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
468  PAPIERROR( "munmap of fd = %d returned error: %s",
469  ctl->events[i].event_fd, strerror( errno ) );
470  return PAPI_ESYS;
471  }
472  }
473 
474  if ( close( ctl->events[i].event_fd ) ) {
475  PAPIERROR( "close of fd = %d returned error: %s",
476  ctl->events[i].event_fd, strerror( errno ) );
477  return PAPI_ESYS;
478  } else {
479  num_closed++;
480  }
481  ctl->events[i].event_opened=0;
482  }
483  }
484  else {
485  events_not_opened++;
486  }
487  }
488 
489  /* Close the group leaders last */
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 
505  if ( close( ctl->events[i].event_fd ) ) {
506  PAPIERROR( "close of fd = %d returned error: %s",
507  ctl->events[i].event_fd, strerror( errno ) );
508  return PAPI_ESYS;
509  } else {
510  num_closed++;
511  }
512  ctl->events[i].event_opened=0;
513  }
514  }
515  }
516 
517 
518  if (ctl->num_events!=num_closed) {
519  if (ctl->num_events!=(num_closed+events_not_opened)) {
520  PAPIERROR("Didn't close all events: "
521  "Closed %d Not Opened: %d Expected %d\n",
522  num_closed,events_not_opened,ctl->num_events);
523  return PAPI_EBUG;
524  }
525  }
526 
527  ctl->num_events=0;
528 
529  ctx->state &= ~PERF_EVENTS_OPENED;
530 
531  return PAPI_OK;
532 }
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:259
return PAPI_OK
Definition: linux-nvml.c:497
uint32_t nr_mmap_pages
int i
Definition: fileop.c:140
#define PAPI_ESYS
Definition: papi.h:255
#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 75 of file perf_event_uncore.c.

78 {
79  unsigned int format = 0;
80 
81  /* if we need read format options for multiplexing, add them now */
82  if (multiplex) {
83  format |= PERF_FORMAT_TOTAL_TIME_ENABLED;
84  format |= PERF_FORMAT_TOTAL_TIME_RUNNING;
85  }
86 
87  /* If we are not using inherit, add the group read options */
88  if (!inherit) {
89  if (format_group) {
90  format |= PERF_FORMAT_GROUP;
91  }
92  }
93 
94  SUBDBG("multiplex: %d, inherit: %d, group_leader: %d, format: %#x\n",
95  multiplex, inherit, format_group, format);
96 
97  return format;
98 }
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 175 of file perf_event_uncore.c.

175  {
176 
177  int ret;
178 
179  /* These mappings are approximate.
180  EINVAL in particular can mean lots of different things */
181  switch(perf_event_error) {
182  case EPERM:
183  case EACCES:
184  ret = PAPI_EPERM;
185  break;
186  case ENODEV:
187  case EOPNOTSUPP:
188  ret = PAPI_ENOSUPP;
189  break;
190  case ENOENT:
191  ret = PAPI_ENOEVNT;
192  break;
193  case ENOSYS:
194  case EAGAIN:
195  case EBUSY:
196  case E2BIG:
197  ret = PAPI_ESYS;
198  break;
199  case ENOMEM:
200  ret = PAPI_ENOMEM;
201  break;
202  case EINVAL:
203  default:
204  ret = PAPI_EINVAL;
205  break;
206  }
207  return ret;
208 }
#define PAPI_ENOEVNT
Definition: papi.h:260
#define PAPI_ENOSUPP
Definition: papi.h:271
return PAPI_EINVAL
Definition: linux-nvml.c:436
#define PAPI_EPERM
Definition: papi.h:268
long long ret
Definition: iozone.c:1346
#define PAPI_ESYS
Definition: papi.h:255
#define PAPI_ENOMEM
Definition: papi.h:254

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 301 of file perf_event_uncore.c.

302 {
303 
304  int i, ret = PAPI_OK;
305  long pid;
306 
307  if (ctl->granularity==PAPI_GRN_SYS) {
308  pid = -1;
309  }
310  else {
311  pid = ctl->tid;
312  }
313 
314  for( i = 0; i < ctl->num_events; i++ ) {
315 
316  ctl->events[i].event_opened=0;
317 
318  /* set up the attr structure. We don't set up all fields here */
319  /* as some have already been set up previously. */
320 
321 /*
322  * The following code controls how the uncore component interfaces with the
323  * kernel for uncore events. The code inside the ifdef will use grouping of
324  * uncore events which can make the cost of reading the results more efficient.
325  * The problem with it is that the uncore component supports 20 different uncore
326  * PMU's. The kernel requires that all events in a group must be for the same PMU.
327  * This means that with grouping enabled papi applications can count events on only
328  * one of the 20 PMU's during a run.
329  *
330  * The code inside the else clause treats each event in the event set as
331  * independent. When running in this mode the kernel allows the papi multiple
332  * uncore PMU's at the same time.
333  *
334  * Example:
335  * An application wants to measure all the L3 cache write requests.
336  * The event to do this is part of a cbox pmu (there are 8 cbox pmu's).
337  * When built with the code in the ifdef, the application would have to be
338  * run 8 times and count write requests from one pmu at a time.
339  * When built with the code in the else, the write requests in all 8 cbox
340  * pmu's could be counted in the same run.
341  *
342  */
343 // #define GROUPIT 1 // remove the comment on this line to force event grouping
344 #ifdef GROUPIT
345  /* group leader (event 0) is special */
346  /* If we're multiplexed, everyone is a group leader */
347  if (( i == 0 ) || (ctl->multiplexed)) {
348  ctl->events[i].attr.pinned = !ctl->multiplexed;
349  ctl->events[i].attr.disabled = 1;
350  ctl->events[i].group_leader_fd=-1;
351  ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed,
352  ctl->inherit,
353  !ctl->multiplexed );
354  } else {
355  ctl->events[i].attr.pinned=0;
356  ctl->events[i].attr.disabled = 0;
357  ctl->events[i].group_leader_fd=ctl->events[0].event_fd,
358  ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed,
359  ctl->inherit,
360  0 );
361  }
362 #else
363  ctl->events[i].attr.pinned = !ctl->multiplexed;
364  ctl->events[i].attr.disabled = 1;
365  ctl->inherit = 1;
366  ctl->events[i].group_leader_fd=-1;
367  ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed, ctl->inherit, 0 );
368 #endif
369 
370 
371  /* try to open */
372  ctl->events[i].event_fd = sys_perf_event_open( &ctl->events[i].attr,
373  pid,
374  ctl->events[i].cpu,
375  ctl->events[i].group_leader_fd,
376  0 /* flags */
377  );
378 
379  /* Try to match Linux errors to PAPI errors */
380  if ( ctl->events[i].event_fd == -1 ) {
381  SUBDBG("sys_perf_event_open returned error on event #%d."
382  " Error: %s\n",
383  i, strerror( errno ) );
385 
386  goto open_peu_cleanup;
387  }
388 
389  SUBDBG ("sys_perf_event_open: tid: %ld, cpu_num: %d,"
390  " group_leader/fd: %d, event_fd: %d,"
391  " read_format: %"PRIu64"\n",
392  pid, ctl->events[i].cpu, ctl->events[i].group_leader_fd,
393  ctl->events[i].event_fd, ctl->events[i].attr.read_format);
394 
395  ctl->events[i].event_opened=1;
396  }
397 
398 
399  /* in many situations the kernel will indicate we opened fine */
400  /* yet things will fail later. So we need to double check */
401  /* we actually can use the events we've set up. */
402 
403  /* This is not necessary if we are multiplexing, and in fact */
404  /* we cannot do this properly if multiplexed because */
405  /* PERF_EVENT_IOC_RESET does not reset the time running info */
406  if (!ctl->multiplexed) {
407  ret = check_scheduability( ctx, ctl);
408 
409  if ( ret != PAPI_OK ) {
410  /* the last event did open, so we need to bump the counter */
411  /* before doing the cleanup */
412  i++;
413  goto open_peu_cleanup;
414  }
415  }
416 
417  /* Now that we've successfully opened all of the events, do whatever */
418  /* "tune-up" is needed to attach the mmap'd buffers, signal handlers, */
419  /* and so on. */
420  for ( i = 0; i < ctl->num_events; i++ ) {
421 
422  /* No sampling if uncore */
423  ctl->events[i].mmap_buf = NULL;
424  }
425 
426  /* Set num_evts only if completely successful */
427  ctx->state |= PERF_EVENTS_OPENED;
428 
429  return PAPI_OK;
430 
431 open_peu_cleanup:
432  /* We encountered an error, close up the fds we successfully opened. */
433  /* We go backward in an attempt to close group leaders last, although */
434  /* That's probably not strictly necessary. */
435  while ( i > 0 ) {
436  i--;
437  if (ctl->events[i].event_fd>=0) {
438  close( ctl->events[i].event_fd );
439  ctl->events[i].event_opened=0;
440  }
441  }
442 
443  return ret;
444 }
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:497
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:366

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 124 of file perf_event_uncore.c.

126 {
127  int ret;
128 
129  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);
130  SUBDBG(" type: %d\n",hw_event->type);
131  SUBDBG(" size: %d\n",hw_event->size);
132  SUBDBG(" config: %#"PRIx64" (%"PRIu64")\n",hw_event->config,
133  hw_event->config);
134  SUBDBG(" sample_period: %"PRIu64"\n",hw_event->sample_period);
135  SUBDBG(" sample_type: %"PRIu64"\n",hw_event->sample_type);
136  SUBDBG(" read_format: %"PRIu64"\n",hw_event->read_format);
137  SUBDBG(" disabled: %d\n",hw_event->disabled);
138  SUBDBG(" inherit: %d\n",hw_event->inherit);
139  SUBDBG(" pinned: %d\n",hw_event->pinned);
140  SUBDBG(" exclusive: %d\n",hw_event->exclusive);
141  SUBDBG(" exclude_user: %d\n",hw_event->exclude_user);
142  SUBDBG(" exclude_kernel: %d\n",hw_event->exclude_kernel);
143  SUBDBG(" exclude_hv: %d\n",hw_event->exclude_hv);
144  SUBDBG(" exclude_idle: %d\n",hw_event->exclude_idle);
145  SUBDBG(" mmap: %d\n",hw_event->mmap);
146  SUBDBG(" comm: %d\n",hw_event->comm);
147  SUBDBG(" freq: %d\n",hw_event->freq);
148  SUBDBG(" inherit_stat: %d\n",hw_event->inherit_stat);
149  SUBDBG(" enable_on_exec: %d\n",hw_event->enable_on_exec);
150  SUBDBG(" task: %d\n",hw_event->task);
151  SUBDBG(" watermark: %d\n",hw_event->watermark);
152  SUBDBG(" precise_ip: %d\n",hw_event->precise_ip);
153  SUBDBG(" mmap_data: %d\n",hw_event->mmap_data);
154  SUBDBG(" sample_id_all: %d\n",hw_event->sample_id_all);
155  SUBDBG(" exclude_host: %d\n",hw_event->exclude_host);
156  SUBDBG(" exclude_guest: %d\n",hw_event->exclude_guest);
157  SUBDBG(" exclude_callchain_kernel: %d\n",hw_event->exclude_callchain_kernel);
158  SUBDBG(" exclude_callchain_user: %d\n",hw_event->exclude_callchain_user);
159  SUBDBG(" wakeup_watermark: %d\n",hw_event->wakeup_watermark);
160  SUBDBG(" bp_type: %d\n",hw_event->bp_type);
161  SUBDBG(" config1: %#lx (%lu)\n",hw_event->config1,hw_event->config1);
162  SUBDBG(" config2: %#lx (%lu)\n",hw_event->config2,hw_event->config2);
163  SUBDBG(" branch_sample_type: %lu\n",hw_event->branch_sample_type);
164  SUBDBG(" sample_regs_user: %lu\n",hw_event->sample_regs_user);
165  SUBDBG(" sample_stack_user: %d\n",hw_event->sample_stack_user);
166 
167  ret = syscall( __NR_perf_event_open, hw_event, pid, cpu, group_fd, flags );
168  SUBDBG("Returned %d %d %s\n",ret,
169  ret<0?errno:0,
170  ret<0?strerror(errno):" ");
171  return ret;
172 }
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 49 of file perf_event_uncore.c.

int our_cidx
static

Definition at line 53 of file perf_event_uncore.c.

struct native_event_table_t uncore_native_event_table

Definition at line 52 of file perf_event_uncore.c.