perf_event.c File Reference

Include dependency graph for perf_event.c:

Go to the source code of this file.

Data Structures

struct  ip_event
struct  lost_event
union  perf_sample_event_t

Defines

#define PERF_EVENTS_OPENED   0x01
#define PERF_EVENTS_RUNNING   0x02
#define WAKEUP_COUNTER_OVERFLOW   0
#define WAKEUP_PROFILING   -1
#define WAKEUP_MODE_COUNTER_OVERFLOW   0
#define WAKEUP_MODE_PROFILING   1
#define PAPI_REFRESH_VALUE   1
#define READ_BUFFER_SIZE   (3 + (2 * PERF_EVENT_MAX_MPX_COUNTERS))

Functions

static int _pe_shutdown_thread (hwd_context_t *ctx)
static int _pe_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _pe_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
static int _pe_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _pe_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _pe_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _pe_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int _pe_libpfm4_get_cidx ()
static int _pe_set_domain (hwd_control_state_t *ctl, int domain)
static int processor_supported (int vendor, int family)
static int pe_vendor_fixups (papi_vector_t *vector)
static int bug_format_group (void)
static int bug_sync_read (void)
static int fcntl_setown_fd (int fd)
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_permissions (unsigned long tid, unsigned int cpu_num, unsigned int domain, unsigned int granularity, unsigned int multiplex, unsigned int inherit)
static int check_scheduability (pe_context_t *ctx, pe_control_t *ctl, int idx)
static int tune_up_fd (pe_control_t *ctl, int evt_idx)
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 _pe_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _pe_init_thread (hwd_context_t *hwd_ctx)
static int _pe_init_control_state (hwd_control_state_t *ctl)
static int _pe_detect_rdpmc (int default_domain)
static int _pe_init_component (int cidx)
static int _pe_shutdown_component (void)
static int _pe_ntv_enum_events (unsigned int *PapiEventCode, int modifier)
static int _pe_ntv_name_to_code (char *name, unsigned int *event_code)
static int _pe_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
static int _pe_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len)
static int _pe_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info)
static uint64_t mmap_read_head (pe_event_info_t *pe)
static void mmap_write_tail (pe_event_info_t *pe, uint64_t tail)
static void mmap_read (int cidx, ThreadInfo_t **thr, pe_event_info_t *pe, int profile_index)
static int find_profile_index (EventSetInfo_t *ESI, int evt_idx, int *flags, unsigned int *native_index, int *profile_index)
static int process_smpl_buf (int evt_idx, ThreadInfo_t **thr, int cidx)
static void _pe_dispatch_timer (int n, hwd_siginfo_t *info, void *uc)
static int _pe_stop_profiling (ThreadInfo_t *thread, EventSetInfo_t *ESI)
static int _pe_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
static int _pe_set_profile (EventSetInfo_t *ESI, int EventIndex, int threshold)

Variables

papi_vector_t _perf_event_vector
struct native_event_table_t perf_native_event_table
static int our_cidx

Define Documentation

#define PAPI_REFRESH_VALUE   1

Definition at line 99 of file perf_event.c.

#define PERF_EVENTS_OPENED   0x01

Definition at line 58 of file perf_event.c.

#define PERF_EVENTS_RUNNING   0x02

Definition at line 59 of file perf_event.c.

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

Definition at line 463 of file perf_event.c.

#define WAKEUP_COUNTER_OVERFLOW   0

Definition at line 85 of file perf_event.c.

#define WAKEUP_MODE_COUNTER_OVERFLOW   0

Definition at line 88 of file perf_event.c.

#define WAKEUP_MODE_PROFILING   1

Definition at line 89 of file perf_event.c.

#define WAKEUP_PROFILING   -1

Definition at line 86 of file perf_event.c.


Function Documentation

static int _pe_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
) [static]

Definition at line 1327 of file perf_event.c.

01328 {
01329    int ret;
01330    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
01331    pe_control_t *pe_ctl = NULL;
01332 
01333    switch ( code ) {
01334       case PAPI_MULTIPLEX:
01335        pe_ctl = ( pe_control_t * ) ( option->multiplex.ESI->ctl_state );
01336        ret = check_permissions( pe_ctl->tid, pe_ctl->cpu, pe_ctl->domain,
01337                     pe_ctl->granularity,
01338                     1, pe_ctl->inherit );
01339            if (ret != PAPI_OK) {
01340           return ret;
01341        }
01342 
01343        /* looks like we are allowed, so set multiplexed attribute */
01344        pe_ctl->multiplexed = 1;
01345        ret = _pe_update_control_state( pe_ctl, NULL,
01346                         pe_ctl->num_events, pe_ctx );
01347        if (ret != PAPI_OK) {
01348           pe_ctl->multiplexed = 0;
01349        }
01350        return ret;
01351 
01352       case PAPI_ATTACH:
01353        pe_ctl = ( pe_control_t * ) ( option->attach.ESI->ctl_state );
01354        ret = check_permissions( option->attach.tid, pe_ctl->cpu,
01355                   pe_ctl->domain, pe_ctl->granularity,
01356                   pe_ctl->multiplexed,
01357                     pe_ctl->inherit );
01358        if (ret != PAPI_OK) {
01359           return ret;
01360        }
01361 
01362        pe_ctl->tid = option->attach.tid;
01363 
01364        /* If events have been already been added, something may */
01365        /* have been done to the kernel, so update */
01366        ret =_pe_update_control_state( pe_ctl, NULL,
01367                         pe_ctl->num_events, pe_ctx);
01368 
01369        return ret;
01370 
01371       case PAPI_DETACH:
01372        pe_ctl = ( pe_control_t *) ( option->attach.ESI->ctl_state );
01373 
01374        pe_ctl->tid = 0;
01375        return PAPI_OK;
01376 
01377       case PAPI_CPU_ATTACH:
01378        pe_ctl = ( pe_control_t *) ( option->cpu.ESI->ctl_state );
01379        ret = check_permissions( pe_ctl->tid, option->cpu.cpu_num,
01380                     pe_ctl->domain, pe_ctl->granularity,
01381                     pe_ctl->multiplexed,
01382                     pe_ctl->inherit );
01383            if (ret != PAPI_OK) {
01384            return ret;
01385        }
01386        /* looks like we are allowed so set cpu number */
01387 
01388        /* this tells the kernel not to count for a thread   */
01389        /* should we warn if we try to set both?  perf_event */
01390        /* will reject it.                                   */
01391        pe_ctl->tid = -1;
01392 
01393        pe_ctl->cpu = option->cpu.cpu_num;
01394 
01395        return PAPI_OK;
01396 
01397       case PAPI_DOMAIN:
01398        pe_ctl = ( pe_control_t *) ( option->domain.ESI->ctl_state );
01399        ret = check_permissions( pe_ctl->tid, pe_ctl->cpu,
01400                     option->domain.domain,
01401                     pe_ctl->granularity,
01402                     pe_ctl->multiplexed,
01403                     pe_ctl->inherit );
01404            if (ret != PAPI_OK) {
01405           return ret;
01406        }
01407        /* looks like we are allowed, so set event set level counting domains */
01408        pe_ctl->domain = option->domain.domain;
01409        return PAPI_OK;
01410 
01411       case PAPI_GRANUL:
01412        pe_ctl = (pe_control_t *) ( option->granularity.ESI->ctl_state );
01413 
01414        /* FIXME: we really don't support this yet */
01415 
01416            switch ( option->granularity.granularity  ) {
01417               case PAPI_GRN_PROCG:
01418               case PAPI_GRN_SYS_CPU:
01419               case PAPI_GRN_PROC:
01420            return PAPI_ECMP;
01421 
01422           /* Currently we only support thread and CPU granularity */
01423               case PAPI_GRN_SYS:
01424            pe_ctl->granularity=PAPI_GRN_SYS;
01425            pe_ctl->cpu=_papi_getcpu();
01426            break;
01427 
01428               case PAPI_GRN_THR:
01429            pe_ctl->granularity=PAPI_GRN_THR;
01430            break;
01431 
01432 
01433               default:
01434            return PAPI_EINVAL;
01435        }
01436            return PAPI_OK;
01437 
01438       case PAPI_INHERIT:
01439        pe_ctl = (pe_control_t *) ( option->inherit.ESI->ctl_state );
01440        ret = check_permissions( pe_ctl->tid, pe_ctl->cpu, pe_ctl->domain,
01441                   pe_ctl->granularity, pe_ctl->multiplexed,
01442                     option->inherit.inherit );
01443            if (ret != PAPI_OK) {
01444           return ret;
01445        }
01446        /* looks like we are allowed, so set the requested inheritance */
01447        if (option->inherit.inherit) {
01448           /* children will inherit counters */
01449           pe_ctl->inherit = 1;
01450        } else {
01451           /* children won't inherit counters */
01452           pe_ctl->inherit = 0;
01453        }
01454        return PAPI_OK;
01455 
01456       case PAPI_DATA_ADDRESS:
01457        return PAPI_ENOSUPP;
01458 #if 0
01459        pe_ctl = (pe_control_t *) (option->address_range.ESI->ctl_state);
01460        ret = set_default_domain( pe_ctl, option->address_range.domain );
01461        if ( ret != PAPI_OK ) {
01462           return ret;
01463        }
01464        set_drange( pe_ctx, pe_ctl, option );
01465        return PAPI_OK;
01466 #endif
01467       case PAPI_INSTR_ADDRESS:
01468        return PAPI_ENOSUPP;
01469 #if 0
01470        pe_ctl = (pe_control_t *) (option->address_range.ESI->ctl_state);
01471        ret = set_default_domain( pe_ctl, option->address_range.domain );
01472        if ( ret != PAPI_OK ) {
01473           return ret;
01474        }
01475        set_irange( pe_ctx, pe_ctl, option );
01476        return PAPI_OK;
01477 #endif
01478 
01479       case PAPI_DEF_ITIMER:
01480        /* What should we be checking for here?                   */
01481        /* This seems like it should be OS-specific not component */
01482        /* specific.                                              */
01483 
01484        return PAPI_OK;
01485 
01486       case PAPI_DEF_MPX_NS:
01487        /* Defining a given ns per set is not current supported */
01488        return PAPI_ENOSUPP;
01489 
01490       case PAPI_DEF_ITIMER_NS:
01491        /* We don't support this... */
01492        return PAPI_OK;
01493 
01494       default:
01495        return PAPI_ENOSUPP;
01496    }
01497 }

Here is the call graph for this function:

static int _pe_detect_rdpmc ( int  default_domain  )  [static]

Definition at line 1542 of file perf_event.c.

01542                                                 {
01543 
01544   struct perf_event_attr pe;
01545   int fd,rdpmc_exists=1;
01546   void *addr;
01547   struct perf_event_mmap_page *our_mmap;
01548 
01549   /* Create a fake instructions event so we can read a mmap page */
01550   memset(&pe,0,sizeof(struct perf_event_attr));
01551 
01552   pe.type=PERF_TYPE_HARDWARE;
01553   pe.size=sizeof(struct perf_event_attr);
01554   pe.config=PERF_COUNT_HW_INSTRUCTIONS;
01555 
01556   /* There should probably be a helper function to handle this      */
01557   /* we break on some ARM because there is no support for excluding */
01558   /* kernel.                                                        */
01559   if (default_domain & PAPI_DOM_KERNEL ) {
01560   }
01561   else {
01562     pe.exclude_kernel=1;
01563   }
01564   fd=sys_perf_event_open(&pe,0,-1,-1,0);
01565   if (fd<0) {
01566     return PAPI_ESYS;
01567   }
01568 
01569   /* create the mmap page */
01570   addr=mmap(NULL, 4096, PROT_READ, MAP_SHARED,fd,0);
01571   if (addr == (void *)(-1)) {
01572     close(fd);
01573     return PAPI_ESYS;
01574   }
01575 
01576   /* get the rdpmc info */
01577   our_mmap=(struct perf_event_mmap_page *)addr;
01578   if (our_mmap->cap_usr_rdpmc==0) {
01579     rdpmc_exists=0;
01580   }
01581 
01582   /* close the fake event */
01583   munmap(addr,4096);
01584   close(fd);
01585 
01586   return rdpmc_exists;
01587 
01588 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void _pe_dispatch_timer ( int  n,
hwd_siginfo_t info,
void *  uc 
) [static]

Definition at line 1926 of file perf_event.c.

01927 {
01928   ( void ) n;                           /*unused */
01929   _papi_hwi_context_t hw_context;
01930   int found_evt_idx = -1, fd = info->si_fd;
01931   caddr_t address;
01932   ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
01933   int i;
01934   pe_control_t *ctl;
01935   int cidx = _perf_event_vector.cmp_info.CmpIdx;
01936 
01937   if ( thread == NULL ) {
01938     PAPIERROR( "thread == NULL in _papi_pe_dispatch_timer for fd %d!", fd );
01939     return;
01940   }
01941 
01942   if ( thread->running_eventset[cidx] == NULL ) {
01943     PAPIERROR( "thread->running_eventset == NULL in "
01944            "_papi_pe_dispatch_timer for fd %d!",fd );
01945     return;
01946   }
01947 
01948   if ( thread->running_eventset[cidx]->overflow.flags == 0 ) {
01949     PAPIERROR( "thread->running_eventset->overflow.flags == 0 in "
01950            "_papi_pe_dispatch_timer for fd %d!", fd );
01951     return;
01952   }
01953 
01954   hw_context.si = info;
01955   hw_context.ucontext = ( hwd_ucontext_t * ) uc;
01956 
01957   if ( thread->running_eventset[cidx]->overflow.flags & 
01958        PAPI_OVERFLOW_FORCE_SW ) {
01959     address = GET_OVERFLOW_ADDRESS( hw_context );
01960     _papi_hwi_dispatch_overflow_signal( ( void * ) &hw_context, 
01961                     address, NULL, 0,
01962                     0, &thread, cidx );
01963     return;
01964   }
01965 
01966   if ( thread->running_eventset[cidx]->overflow.flags !=
01967        PAPI_OVERFLOW_HARDWARE ) {
01968     PAPIERROR( "thread->running_eventset->overflow.flags is set to "
01969                  "something other than PAPI_OVERFLOW_HARDWARE or "
01970            "PAPI_OVERFLOW_FORCE_SW for fd %d (%#x)",
01971            fd , thread->running_eventset[cidx]->overflow.flags);
01972   }
01973 
01974   /* convoluted way to get ctl */
01975   ctl= thread->running_eventset[cidx]->ctl_state;
01976 
01977   /* See if the fd is one that's part of the this thread's context */
01978   for( i=0; i < ctl->num_events; i++ ) {
01979     if ( fd == ctl->events[i].event_fd ) {
01980       found_evt_idx = i;
01981       break;
01982     }
01983   }
01984 
01985   if ( found_evt_idx == -1 ) {
01986     PAPIERROR( "Unable to find fd %d among the open event fds "
01987            "_papi_hwi_dispatch_timer!", fd );
01988     return;
01989   }
01990         
01991   if (ioctl( fd, PERF_EVENT_IOC_DISABLE, NULL ) == -1 ) {
01992       PAPIERROR("ioctl(PERF_EVENT_IOC_DISABLE) failed");
01993   }
01994 
01995   if ( ( thread->running_eventset[cidx]->state & PAPI_PROFILING ) && 
01996        !( thread->running_eventset[cidx]->profile.flags & 
01997       PAPI_PROFIL_FORCE_SW ) ) {
01998     process_smpl_buf( found_evt_idx, &thread, cidx );
01999   }
02000   else {
02001     uint64_t ip;
02002     unsigned int head;
02003     pe_event_info_t *pe = &(ctl->events[found_evt_idx]);
02004     unsigned char *data = ((unsigned char*)pe->mmap_buf) + getpagesize(  );
02005 
02006     /*
02007      * Read up the most recent IP from the sample in the mmap buffer.  To
02008      * do this, we make the assumption that all of the records in the
02009      * mmap buffer are the same size, and that they all contain the IP as
02010      * their only record element.  This means that we can use the
02011      * data_head element from the user page and move backward one record
02012      * from that point and read the data.  Since we don't actually need
02013      * to access the header of the record, we can just subtract 8 (size
02014      * of the IP) from data_head and read up that word from the mmap
02015      * buffer.  After we subtract 8, we account for mmap buffer wrapping
02016      * by AND'ing this offset with the buffer mask.
02017      */
02018     head = mmap_read_head( pe );
02019 
02020     if ( head == 0 ) {
02021       PAPIERROR( "Attempting to access memory which may be inaccessable" );
02022       return;
02023     }
02024     ip = *( uint64_t * ) ( data + ( ( head - 8 ) & pe->mask ) );
02025     /*
02026      * Update the tail to the current head pointer. 
02027      *
02028      * Note: that if we were to read the record at the tail pointer,
02029      * rather than the one at the head (as you might otherwise think
02030      * would be natural), we could run into problems.  Signals don't
02031      * stack well on Linux, particularly if not using RT signals, and if
02032      * they come in rapidly enough, we can lose some.  Overtime, the head
02033      * could catch up to the tail and monitoring would be stopped, and
02034      * since no more signals are coming in, this problem will never be
02035      * resolved, resulting in a complete loss of overflow notification
02036      * from that point on.  So the solution we use here will result in
02037      * only the most recent IP value being read every time there are two
02038      * or more samples in the buffer (for that one overflow signal).  But
02039      * the handler will always bring up the tail, so the head should
02040      * never run into the tail.
02041      */
02042     mmap_write_tail( pe, head );
02043 
02044     /*
02045      * The fourth parameter is supposed to be a vector of bits indicating
02046      * the overflowed hardware counters, but it's not really clear that
02047      * it's useful, because the actual hardware counters used are not
02048      * exposed to the PAPI user.  For now, I'm just going to set the bit
02049      * that indicates which event register in the array overflowed.  The
02050      * result is that the overflow vector will not be identical to the
02051      * perfmon implementation, and part of that is due to the fact that
02052      * which hardware register is actually being used is opaque at the
02053      * user level (the kernel event dispatcher hides that info).
02054      */
02055 
02056     _papi_hwi_dispatch_overflow_signal( ( void * ) &hw_context,
02057                     ( caddr_t ) ( unsigned long ) ip,
02058                     NULL, ( 1 << found_evt_idx ), 0,
02059                     &thread, cidx );
02060 
02061   }
02062 
02063   /* Restart the counters */
02064   if (ioctl( fd, PERF_EVENT_IOC_REFRESH, PAPI_REFRESH_VALUE ) == -1) {
02065     PAPIERROR( "overflow refresh failed", 0 );
02066   }
02067 }

Here is the call graph for this function:

static int _pe_init_component ( int  cidx  )  [static]

Definition at line 1593 of file perf_event.c.

01594 {
01595 
01596   int retval;
01597   int paranoid_level;
01598 
01599   FILE *fff;
01600 
01601   our_cidx=cidx;
01602 
01603   /* The is the official way to detect if perf_event support exists */
01604   /* The file is called perf_counter_paranoid on 2.6.31             */
01605   /* currently we are lazy and do not support 2.6.31 kernels        */
01606   fff=fopen("/proc/sys/kernel/perf_event_paranoid","r");
01607   if (fff==NULL) {
01608     strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
01609         "perf_event support not detected",PAPI_MAX_STR_LEN);
01610     return PAPI_ENOCMP;
01611   }
01612 
01613   /* 2 means no kernel measurements allowed   */
01614   /* 1 means normal counter access            */
01615   /* 0 means you can access CPU-specific data */
01616   /* -1 means no restrictions                 */
01617   retval=fscanf(fff,"%d",&paranoid_level);
01618   if (retval!=1) fprintf(stderr,"Error reading paranoid level\n");
01619   fclose(fff);
01620 
01621   if ((paranoid_level==2) && (getuid()!=0)) {
01622      SUBDBG("/proc/sys/kernel/perf_event_paranoid prohibits kernel counts");
01623      _papi_hwd[cidx]->cmp_info.available_domains &=~PAPI_DOM_KERNEL;
01624   }
01625 
01626   /* Detect NMI watchdog which can steal counters */
01627   if (_linux_detect_nmi_watchdog()) {
01628     SUBDBG("The Linux nmi_watchdog is using one of the performance "
01629        "counters, reducing the total number available.\n");
01630   }
01631   /* Kernel multiplexing is broken prior to kernel 2.6.34 */
01632   /* The fix was probably git commit:                     */
01633   /*     45e16a6834b6af098702e5ea6c9a40de42ff77d8         */
01634   if (_papi_os_info.os_version < LINUX_VERSION(2,6,34)) {
01635     _papi_hwd[cidx]->cmp_info.kernel_multiplex = 0;
01636     _papi_hwd[cidx]->cmp_info.num_mpx_cntrs = PAPI_MAX_SW_MPX_EVENTS;
01637   }
01638   else {
01639     _papi_hwd[cidx]->cmp_info.kernel_multiplex = 1;
01640     _papi_hwd[cidx]->cmp_info.num_mpx_cntrs = PERF_EVENT_MAX_MPX_COUNTERS;
01641   }
01642 
01643   /* Check that processor is supported */
01644   if (processor_supported(_papi_hwi_system_info.hw_info.vendor,
01645               _papi_hwi_system_info.hw_info.cpuid_family)!=
01646       PAPI_OK) {
01647     fprintf(stderr,"warning, your processor is unsupported\n");
01648     /* should not return error, as software events should still work */
01649   }
01650 
01651   /* Setup mmtimers, if appropriate */
01652   retval=mmtimer_setup();
01653   if (retval) {
01654     strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
01655         "Error initializing mmtimer",PAPI_MAX_STR_LEN);
01656     return retval;
01657   }
01658 
01659    /* Set the overflow signal */
01660    _papi_hwd[cidx]->cmp_info.hardware_intr_sig = SIGRTMIN + 2;
01661 
01662    /* Run Vendor-specific fixups */
01663    pe_vendor_fixups(_papi_hwd[cidx]);
01664 
01665    /* Detect if we can use rdpmc (or equivalent) */
01666    /* We currently do not use rdpmc as it is slower in tests */
01667    /* than regular read (as of Linux 3.5)                    */
01668    retval=_pe_detect_rdpmc(_papi_hwd[cidx]->cmp_info.default_domain);
01669    if (retval < 0 ) {
01670       strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
01671         "sys_perf_event_open() failed, perf_event support for this platform may be broken",PAPI_MAX_STR_LEN);
01672 
01673        return retval;
01674     }
01675    _papi_hwd[cidx]->cmp_info.fast_counter_read = retval;
01676 
01677    /* Run the libpfm4-specific setup */
01678    retval = _papi_libpfm4_init(_papi_hwd[cidx]);
01679    if (retval) {
01680      strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
01681          "Error initializing libpfm4",PAPI_MAX_STR_LEN);
01682      return retval;
01683    }
01684 
01685    retval = _pe_libpfm4_init(_papi_hwd[cidx], cidx,
01686                    &perf_native_event_table,
01687                                PMU_TYPE_CORE | PMU_TYPE_OS);
01688    if (retval) {
01689      strncpy(_papi_hwd[cidx]->cmp_info.disabled_reason,
01690          "Error initializing libpfm4",PAPI_MAX_STR_LEN);
01691      return retval;
01692    }
01693 
01694    return PAPI_OK;
01695 
01696 }

Here is the call graph for this function:

static int _pe_init_control_state ( hwd_control_state_t ctl  )  [static]

Definition at line 1517 of file perf_event.c.

01518 {
01519   pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01520 
01521   /* clear the contents */
01522   memset( pe_ctl, 0, sizeof ( pe_control_t ) );
01523 
01524   /* Set the domain */
01525   _pe_set_domain( ctl, _perf_event_vector.cmp_info.default_domain );    
01526 
01527   /* default granularity */
01528   pe_ctl->granularity= _perf_event_vector.cmp_info.default_granularity;
01529 
01530   /* overflow signal */
01531   pe_ctl->overflow_signal=_perf_event_vector.cmp_info.hardware_intr_sig;
01532 
01533   pe_ctl->cidx=our_cidx;
01534 
01535   /* Set cpu number in the control block to show events */
01536   /* are not tied to specific cpu                       */
01537   pe_ctl->cpu = -1;
01538   return PAPI_OK;
01539 }

Here is the call graph for this function:

static int _pe_init_thread ( hwd_context_t hwd_ctx  )  [static]

Definition at line 1501 of file perf_event.c.

01502 {
01503 
01504   pe_context_t *pe_ctx = ( pe_context_t *) hwd_ctx;
01505 
01506   /* clear the context structure and mark as initialized */
01507   memset( pe_ctx, 0, sizeof ( pe_context_t ) );
01508   pe_ctx->initialized=1;
01509   pe_ctx->event_table=&perf_native_event_table;
01510   pe_ctx->cidx=our_cidx;
01511 
01512   return PAPI_OK;
01513 }

int _pe_libpfm4_get_cidx ( void   ) 

Definition at line 78 of file perf_event.c.

00078                        {
00079     return our_cidx;
00080 }

Here is the caller graph for this function:

static int _pe_ntv_code_to_descr ( unsigned int  EventCode,
char *  ntv_descr,
int  len 
) [static]

Definition at line 1736 of file perf_event.c.

01737                                                       {
01738 
01739    return _pe_libpfm4_ntv_code_to_descr(EventCode,ntv_descr,len,
01740                                           &perf_native_event_table);
01741 }

Here is the call graph for this function:

static int _pe_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
) [static]

Definition at line 1744 of file perf_event.c.

01745                                                    {
01746 
01747   return _pe_libpfm4_ntv_code_to_info(EventCode, info,
01748                                         &perf_native_event_table);
01749 }

Here is the call graph for this function:

static int _pe_ntv_code_to_name ( unsigned int  EventCode,
char *  ntv_name,
int  len 
) [static]

Definition at line 1728 of file perf_event.c.

01729                                                    {
01730    return _pe_libpfm4_ntv_code_to_name(EventCode,
01731                                          ntv_name, len, 
01732                     &perf_native_event_table);
01733 }

Here is the call graph for this function:

static int _pe_ntv_enum_events ( unsigned int *  PapiEventCode,
int  modifier 
) [static]

Definition at line 1715 of file perf_event.c.

01716 {
01717   return _pe_libpfm4_ntv_enum_events(PapiEventCode, modifier,
01718                                        &perf_native_event_table);
01719 }

Here is the call graph for this function:

static int _pe_ntv_name_to_code ( char *  name,
unsigned int *  event_code 
) [static]

Definition at line 1722 of file perf_event.c.

01722                                                             {
01723   return _pe_libpfm4_ntv_name_to_code(name,event_code,
01724                                         &perf_native_event_table);
01725 }

Here is the call graph for this function:

static int _pe_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
) [static]

Definition at line 918 of file perf_event.c.

00920 {
00921     SUBDBG("ENTER: ctx: %p, ctl: %p, events: %p, flags: %#x\n", ctx, ctl, events, flags);
00922 
00923    ( void ) flags;           /*unused */
00924    int i, ret = -1;
00925    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
00926    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
00927    long long papi_pe_buffer[READ_BUFFER_SIZE];
00928    long long tot_time_running, tot_time_enabled, scale;
00929 
00930    /* On kernels before 2.6.33 the TOTAL_TIME_ENABLED and TOTAL_TIME_RUNNING */
00931    /* fields are always 0 unless the counter is disabled.  So if we are on   */
00932    /* one of these kernels, then we must disable events before reading.      */
00933 
00934    /* Elsewhere though we disable multiplexing on kernels before 2.6.34 */
00935    /* so maybe this isn't even necessary.                               */
00936 
00937    if (bug_sync_read()) {
00938       if ( pe_ctx->state & PERF_EVENTS_RUNNING ) {
00939          for ( i = 0; i < pe_ctl->num_events; i++ ) {
00940         /* disable only the group leaders */
00941         if ( pe_ctl->events[i].group_leader_fd == -1 ) {
00942            ret = ioctl( pe_ctl->events[i].event_fd, 
00943                PERF_EVENT_IOC_DISABLE, NULL );
00944            if ( ret == -1 ) {
00945               PAPIERROR("ioctl(PERF_EVENT_IOC_DISABLE) "
00946                "returned an error: ", strerror( errno ));
00947               return PAPI_ESYS;
00948            }
00949         }
00950      }
00951       }
00952    }
00953 
00954 
00955    /* Handle case where we are multiplexing */
00956    if (pe_ctl->multiplexed) {
00957 
00958       /* currently we handle multiplexing by having individual events */
00959       /* so we read from each in turn.                                */
00960 
00961       for ( i = 0; i < pe_ctl->num_events; i++ ) {
00962 
00963          ret = read( pe_ctl->events[i].event_fd, papi_pe_buffer,
00964             sizeof ( papi_pe_buffer ) );
00965          if ( ret == -1 ) {
00966         PAPIERROR("read returned an error: ", strerror( errno ));
00967         return PAPI_ESYS;
00968      }
00969 
00970      /* We should read 3 64-bit values from the counter */
00971      if (ret<(signed)(3*sizeof(long long))) {
00972         PAPIERROR("Error!  short read");
00973         return PAPI_ESYS;
00974      }
00975 
00976          SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
00977             pe_ctl->events[i].event_fd,
00978         (long)pe_ctl->tid, pe_ctl->events[i].cpu, ret);
00979          SUBDBG("read: %lld %lld %lld\n",papi_pe_buffer[0],
00980             papi_pe_buffer[1],papi_pe_buffer[2]);
00981 
00982          tot_time_enabled = papi_pe_buffer[1];
00983          tot_time_running = papi_pe_buffer[2];
00984 
00985          SUBDBG("count[%d] = (papi_pe_buffer[%d] %lld * "
00986         "tot_time_enabled %lld) / tot_time_running %lld\n",
00987         i, 0,papi_pe_buffer[0],
00988         tot_time_enabled,tot_time_running);
00989 
00990          if (tot_time_running == tot_time_enabled) {
00991         /* No scaling needed */
00992         pe_ctl->counts[i] = papi_pe_buffer[0];
00993          } else if (tot_time_running && tot_time_enabled) {
00994         /* Scale factor of 100 to avoid overflows when computing */
00995         /*enabled/running */
00996 
00997         scale = (tot_time_enabled * 100LL) / tot_time_running;
00998         scale = scale * papi_pe_buffer[0];
00999         scale = scale / 100LL;
01000         pe_ctl->counts[i] = scale;
01001      } else {
01002        /* This should not happen, but Phil reports it sometime does. */
01003         SUBDBG("perf_event kernel bug(?) count, enabled, "
01004            "running: %lld, %lld, %lld\n",
01005            papi_pe_buffer[0],tot_time_enabled,
01006            tot_time_running);
01007 
01008         pe_ctl->counts[i] = papi_pe_buffer[0];
01009      }
01010       }
01011    }
01012 
01013    /* Handle cases where we cannot use FORMAT GROUP */
01014    else if (bug_format_group() || pe_ctl->inherit) {
01015 
01016       /* we must read each counter individually */
01017       for ( i = 0; i < pe_ctl->num_events; i++ ) {
01018 
01019          ret = read( pe_ctl->events[i].event_fd, papi_pe_buffer,
01020             sizeof ( papi_pe_buffer ) );
01021          if ( ret == -1 ) {
01022         PAPIERROR("read returned an error: ", strerror( errno ));
01023         return PAPI_ESYS;
01024      }
01025 
01026      /* we should read one 64-bit value from each counter */
01027      if (ret!=sizeof(long long)) {
01028         PAPIERROR("Error!  short read");
01029         PAPIERROR("read: fd: %2d, tid: %ld, cpu: %d, ret: %d",
01030            pe_ctl->events[i].event_fd,
01031            (long)pe_ctl->tid, pe_ctl->events[i].cpu, ret);
01032         return PAPI_ESYS;
01033      }
01034 
01035          SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
01036             pe_ctl->events[i].event_fd, (long)pe_ctl->tid,
01037         pe_ctl->events[i].cpu, ret);
01038          SUBDBG("read: %lld\n",papi_pe_buffer[0]);
01039 
01040      pe_ctl->counts[i] = papi_pe_buffer[0];
01041       }
01042    }
01043 
01044 
01045    /* Handle cases where we are using FORMAT_GROUP   */
01046    /* We assume only one group leader, in position 0 */
01047 
01048    else {
01049       if (pe_ctl->events[0].group_leader_fd!=-1) {
01050      PAPIERROR("Was expecting group leader");
01051       }
01052 
01053       ret = read( pe_ctl->events[0].event_fd, papi_pe_buffer,
01054           sizeof ( papi_pe_buffer ) );
01055 
01056       if ( ret == -1 ) {
01057      PAPIERROR("read returned an error: ", strerror( errno ));
01058      return PAPI_ESYS;
01059       }
01060 
01061       /* we read 1 64-bit value (number of events) then     */
01062       /* num_events more 64-bit values that hold the counts */
01063       if (ret<(signed)((1+pe_ctl->num_events)*sizeof(long long))) {
01064      PAPIERROR("Error! short read");
01065      return PAPI_ESYS;
01066       }
01067 
01068       SUBDBG("read: fd: %2d, tid: %ld, cpu: %d, ret: %d\n",
01069          pe_ctl->events[0].event_fd,
01070          (long)pe_ctl->tid, pe_ctl->events[0].cpu, ret);
01071       {
01072      int j;
01073      for(j=0;j<ret/8;j++) {
01074             SUBDBG("read %d: %lld\n",j,papi_pe_buffer[j]);
01075      }
01076       }
01077 
01078       /* Make sure the kernel agrees with how many events we have */
01079       if (papi_pe_buffer[0]!=pe_ctl->num_events) {
01080      PAPIERROR("Error!  Wrong number of events");
01081      return PAPI_ESYS;
01082       }
01083 
01084       /* put the count values in their proper location */
01085       for(i=0;i<pe_ctl->num_events;i++) {
01086          pe_ctl->counts[i] = papi_pe_buffer[1+i];
01087       }
01088    }
01089 
01090 
01091    /* If we disabled the counters due to the sync_read_bug(), */
01092    /* then we need to re-enable them now.                     */
01093    if (bug_sync_read()) {
01094       if ( pe_ctx->state & PERF_EVENTS_RUNNING ) {
01095          for ( i = 0; i < pe_ctl->num_events; i++ ) {
01096         if ( pe_ctl->events[i].group_leader_fd == -1 ) {
01097            /* this should refresh any overflow counters too */
01098            ret = ioctl( pe_ctl->events[i].event_fd,
01099                 PERF_EVENT_IOC_ENABLE, NULL );
01100            if ( ret == -1 ) {
01101               /* Should never happen */
01102               PAPIERROR("ioctl(PERF_EVENT_IOC_ENABLE) returned an error: ",
01103                 strerror( errno ));
01104               return PAPI_ESYS;
01105            }
01106         }
01107      }
01108       }
01109    }
01110 
01111    /* point PAPI to the values we read */
01112    *events = pe_ctl->counts;
01113 
01114    SUBDBG("EXIT: *events: %p\n", *events);
01115    return PAPI_OK;
01116 }

Here is the call graph for this function:

static int _pe_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 863 of file perf_event.c.

00864 {
00865    int i, ret;
00866    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
00867 
00868    ( void ) ctx;             /*unused */
00869 
00870    /* We need to reset all of the events, not just the group leaders */
00871    for( i = 0; i < pe_ctl->num_events; i++ ) {
00872       ret = ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
00873       if ( ret == -1 ) {
00874      PAPIERROR("ioctl(%d, PERF_EVENT_IOC_RESET, NULL) "
00875            "returned error, Linux says: %s",
00876            pe_ctl->events[i].event_fd, strerror( errno ) );
00877      return PAPI_ESYS;
00878       }
00879    }
00880 
00881    return PAPI_OK;
00882 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _pe_set_domain ( hwd_control_state_t ctl,
int  domain 
) [static]

Definition at line 838 of file perf_event.c.

00839 {
00840    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
00841 
00842    SUBDBG("old control domain %d, new domain %d\n", pe_ctl->domain,domain);
00843    pe_ctl->domain = domain;
00844    return PAPI_OK;
00845 }

Here is the caller graph for this function:

static int _pe_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
) [static]

Definition at line 2100 of file perf_event.c.

02101 {
02102     SUBDBG("ENTER: ESI: %p, EventIndex: %d, threshold: %d\n", ESI, EventIndex, threshold);
02103 
02104   pe_context_t *ctx;
02105   pe_control_t *ctl = (pe_control_t *) ( ESI->ctl_state );
02106   int i, evt_idx, found_non_zero_sample_period = 0, retval = PAPI_OK;
02107   int cidx;
02108 
02109   cidx = ctl->cidx;
02110   ctx = ( pe_context_t *) ( ESI->master->context[cidx] );
02111 
02112   evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
02113 
02114   SUBDBG("Attempting to set overflow for index %d (%d) of EventSet %d\n",
02115      evt_idx,EventIndex,ESI->EventSetIndex);
02116 
02117   if (evt_idx<0) {
02118     SUBDBG("EXIT: evt_idx: %d\n", evt_idx);
02119     return PAPI_EINVAL;
02120   }
02121 
02122   if ( threshold == 0 ) {
02123     /* If this counter isn't set to overflow, it's an error */
02124     if ( ctl->events[evt_idx].attr.sample_period == 0 ) {
02125         SUBDBG("EXIT: PAPI_EINVAL, Tried to clear sample threshold when it was not set\n");
02126         return PAPI_EINVAL;
02127     }
02128   }
02129 
02130   ctl->events[evt_idx].attr.sample_period = threshold;
02131 
02132   /*
02133    * Note that the wakeup_mode field initially will be set to zero
02134    * (WAKEUP_MODE_COUNTER_OVERFLOW) as a result of a call to memset 0 to
02135    * all of the events in the ctl struct.
02136    *
02137    * Is it even set to any other value elsewhere?
02138    */
02139   switch ( ctl->events[evt_idx].wakeup_mode ) {
02140   case WAKEUP_MODE_PROFILING:
02141     /* Setting wakeup_events to special value zero means issue a */
02142     /* wakeup (signal) on every mmap page overflow.              */
02143     ctl->events[evt_idx].attr.wakeup_events = 0;
02144     break;
02145 
02146   case WAKEUP_MODE_COUNTER_OVERFLOW:
02147     /* Can this code ever be called? */
02148 
02149     /* Setting wakeup_events to one means issue a wakeup on every */
02150     /* counter overflow (not mmap page overflow).                 */
02151     ctl->events[evt_idx].attr.wakeup_events = 1;
02152     /* We need the IP to pass to the overflow handler */
02153     ctl->events[evt_idx].attr.sample_type = PERF_SAMPLE_IP;
02154     /* one for the user page, and two to take IP samples */
02155     ctl->events[evt_idx].nr_mmap_pages = 1 + 2;
02156     break;
02157   default:
02158     PAPIERROR( "ctl->wakeup_mode[%d] set to an unknown value - %u",
02159            evt_idx, ctl->events[evt_idx].wakeup_mode);
02160     SUBDBG("EXIT: PAPI_EBUG\n");
02161     return PAPI_EBUG;
02162   }
02163 
02164   /* Check for non-zero sample period */
02165   for ( i = 0; i < ctl->num_events; i++ ) {
02166     if ( ctl->events[evt_idx].attr.sample_period ) {
02167       found_non_zero_sample_period = 1;
02168       break;
02169     }
02170   }
02171 
02172   if ( found_non_zero_sample_period ) {
02173     /* turn on internal overflow flag for this event set */
02174     ctl->overflow = 1;
02175                 
02176     /* Enable the signal handler */
02177     retval = _papi_hwi_start_signal( 
02178                     ctl->overflow_signal, 
02179                     1, ctl->cidx );
02180     if (retval != PAPI_OK) {
02181         SUBDBG("Call to _papi_hwi_start_signal returned: %d\n", retval);
02182     }
02183   } else {
02184     /* turn off internal overflow flag for this event set */
02185     ctl->overflow = 0;
02186                 
02187     /* Remove the signal handler, if there are no remaining non-zero */
02188     /* sample_periods set                                            */
02189     retval = _papi_hwi_stop_signal(ctl->overflow_signal);
02190     if ( retval != PAPI_OK ) {
02191         SUBDBG("Call to _papi_hwi_stop_signal returned: %d\n", retval);
02192         return retval;
02193     }
02194   }
02195 
02196   retval = _pe_update_control_state( ctl, NULL,
02197                      ( (pe_control_t *) (ESI->ctl_state) )->num_events,
02198                      ctx );
02199 
02200   SUBDBG("EXIT: return: %d\n", retval);
02201   return retval;
02202 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _pe_set_profile ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
) [static]

Definition at line 2206 of file perf_event.c.

02207 {
02208   int ret;
02209   int evt_idx;
02210   pe_control_t *ctl = ( pe_control_t *) ( ESI->ctl_state );
02211 
02212   /* Since you can't profile on a derived event, the event is always the */
02213   /* first and only event in the native event list.                      */
02214   evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
02215 
02216   if ( threshold == 0 ) {
02217     SUBDBG( "MUNMAP(%p,%"PRIu64")\n", ctl->events[evt_idx].mmap_buf,
02218         ( uint64_t ) ctl->events[evt_idx].nr_mmap_pages *
02219         getpagesize(  ) );
02220 
02221     if ( ctl->events[evt_idx].mmap_buf ) {
02222       munmap( ctl->events[evt_idx].mmap_buf,
02223           ctl->events[evt_idx].nr_mmap_pages * getpagesize() );
02224     }
02225     ctl->events[evt_idx].mmap_buf = NULL;
02226     ctl->events[evt_idx].nr_mmap_pages = 0;
02227     ctl->events[evt_idx].attr.sample_type &= ~PERF_SAMPLE_IP;
02228     ret = _pe_set_overflow( ESI, EventIndex, threshold );
02229     /* ??? #warning "This should be handled somewhere else" */
02230     ESI->state &= ~( PAPI_OVERFLOWING );
02231     ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
02232 
02233     return ret;
02234   }
02235 
02236   /* Look up the native event code */
02237   if ( ESI->profile.flags & (PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR)) {
02238     /* Not supported yet... */
02239 
02240     return PAPI_ENOSUPP;
02241   }
02242   if ( ESI->profile.flags & PAPI_PROFIL_RANDOM ) {
02243     /* This requires an ability to randomly alter the sample_period within */
02244     /* a given range.  Kernel does not have this ability. FIXME            */
02245     return PAPI_ENOSUPP;
02246   }
02247 
02248   /* Just a guess at how many pages would make this relatively efficient.  */
02249   /* Note that it's "1 +" because of the need for a control page, and the  */
02250   /* number following the "+" must be a power of 2 (1, 4, 8, 16, etc) or   */
02251   /* zero.  This is required to optimize dealing with circular buffer      */
02252   /* wrapping of the mapped pages.                                         */
02253 
02254   ctl->events[evt_idx].nr_mmap_pages = (1+8);
02255   ctl->events[evt_idx].attr.sample_type |= PERF_SAMPLE_IP;
02256 
02257   ret = _pe_set_overflow( ESI, EventIndex, threshold );
02258   if ( ret != PAPI_OK ) return ret;
02259 
02260   return PAPI_OK;
02261 }

Here is the call graph for this function:

static int _pe_shutdown_component ( void   )  [static]

Definition at line 1700 of file perf_event.c.

01700                                {
01701 
01702   /* deallocate our event table */
01703   _pe_libpfm4_shutdown(&_perf_event_vector, &perf_native_event_table);
01704 
01705   /* Shutdown libpfm4 */
01706   _papi_libpfm4_shutdown();
01707 
01708   return PAPI_OK;
01709 }

Here is the call graph for this function:

static int _pe_shutdown_thread ( hwd_context_t ctx  )  [static]

Definition at line 849 of file perf_event.c.

00850 {
00851     pe_context_t *pe_ctx = ( pe_context_t *) ctx;
00852 
00853     pe_ctx->initialized=0;
00854 
00855     return PAPI_OK;
00856 }

static int _pe_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 1120 of file perf_event.c.

01121 {
01122    int ret;
01123    int i;
01124    int did_something = 0;
01125    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
01126    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01127 
01128    /* Reset the counters first.  Is this necessary? */
01129    ret = _pe_reset( pe_ctx, pe_ctl );
01130    if ( ret ) {
01131       return ret;
01132    }
01133 
01134    /* Enable all of the group leaders                */
01135    /* All group leaders have a group_leader_fd of -1 */
01136    for( i = 0; i < pe_ctl->num_events; i++ ) {
01137       if (pe_ctl->events[i].group_leader_fd == -1) {
01138      SUBDBG("ioctl(enable): fd: %d\n", pe_ctl->events[i].event_fd);
01139      ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_ENABLE, NULL) ;
01140 
01141      /* ioctls always return -1 on failure */
01142          if (ret == -1) {
01143             PAPIERROR("ioctl(PERF_EVENT_IOC_ENABLE) failed");
01144             return PAPI_ESYS;
01145      }
01146 
01147      did_something++;
01148       }
01149    }
01150 
01151    if (!did_something) {
01152       PAPIERROR("Did not enable any counters");
01153       return PAPI_EBUG;
01154    }
01155 
01156    pe_ctx->state |= PERF_EVENTS_RUNNING;
01157 
01158    return PAPI_OK;
01159 
01160 }

Here is the call graph for this function:

static int _pe_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 1164 of file perf_event.c.

01165 {
01166     SUBDBG( "ENTER: ctx: %p, ctl: %p\n", ctx, ctl);
01167 
01168    int ret;
01169    int i;
01170    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
01171    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01172 
01173    /* Just disable the group leaders */
01174    for ( i = 0; i < pe_ctl->num_events; i++ ) {
01175       if ( pe_ctl->events[i].group_leader_fd == -1 ) {
01176      ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_DISABLE, NULL);
01177      if ( ret == -1 ) {
01178         PAPIERROR( "ioctl(%d, PERF_EVENT_IOC_DISABLE, NULL) "
01179                "returned error, Linux says: %s",
01180                pe_ctl->events[i].event_fd, strerror( errno ) );
01181         return PAPI_EBUG;
01182      }
01183       }
01184    }
01185 
01186    pe_ctx->state &= ~PERF_EVENTS_RUNNING;
01187 
01188     SUBDBG( "EXIT:\n");
01189    return PAPI_OK;
01190 }

Here is the call graph for this function:

static int _pe_stop_profiling ( ThreadInfo_t thread,
EventSetInfo_t ESI 
) [static]

Definition at line 2071 of file perf_event.c.

02072 {
02073   int i, ret = PAPI_OK;
02074   pe_control_t *ctl;
02075   int cidx;
02076 
02077   ctl=ESI->ctl_state;
02078 
02079   cidx=ctl->cidx;
02080 
02081   /* Loop through all of the events and process those which have mmap */
02082   /* buffers attached.                                                */
02083   for ( i = 0; i < ctl->num_events; i++ ) {
02084     /* Use the mmap_buf field as an indicator of this fd being used for */
02085     /* profiling.                                                       */
02086     if ( ctl->events[i].mmap_buf ) {
02087       /* Process any remaining samples in the sample buffer */
02088       ret = process_smpl_buf( i, &thread, cidx );
02089       if ( ret ) {
02090     PAPIERROR( "process_smpl_buf returned error %d", ret );
02091     return ret;
02092       }
02093     }
02094   }
02095   return ret;
02096 }

Here is the call graph for this function:

static int _pe_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
) [static]

Definition at line 1197 of file perf_event.c.

01200 {
01201    SUBDBG( "ENTER: ctl: %p, native: %p, count: %d, ctx: %p\n", ctl, native, count, ctx);
01202     int i;
01203     int j;
01204     int ret;
01205     int skipped_events=0;
01206     struct native_event_t *ntv_evt;
01207    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
01208    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01209 
01210    /* close all of the existing fds and start over again */
01211    /* In theory we could have finer-grained control and know if             */
01212    /* things were changed, but it's easier to tear things down and rebuild. */
01213    close_pe_events( pe_ctx, pe_ctl );
01214 
01215    /* Calling with count==0 should be OK, it's how things are deallocated */
01216    /* when an eventset is destroyed.                                      */
01217    if ( count == 0 ) {
01218       SUBDBG( "EXIT: Called with count == 0\n" );
01219       return PAPI_OK;
01220    }
01221 
01222    /* set up all the events */
01223    for( i = 0; i < count; i++ ) {
01224       if ( native ) {
01225             // get the native event pointer used for this papi event
01226             int ntv_idx = _papi_hwi_get_ntv_idx((unsigned)(native[i].ni_papi_code));
01227             if (ntv_idx < -1) {
01228                 SUBDBG("papi_event_code: %#x known by papi but not by the component\n", native[i].ni_papi_code);
01229                 continue;
01230             }
01231             // if native index is -1, then we have an event without a mask and need to find the right native index to use
01232             if (ntv_idx == -1) {
01233                 // find the native event index we want by matching for the right papi event code
01234                 for (j=0 ; j<pe_ctx->event_table->num_native_events ; j++) {
01235                     if (pe_ctx->event_table->native_events[j].papi_event_code == native[i].ni_papi_code) {
01236                         ntv_idx = j;
01237                     }
01238                 }
01239             }
01240 
01241             // if native index is still negative, we did not find event we wanted so just return error
01242             if (ntv_idx < 0) {
01243                 SUBDBG("papi_event_code: %#x not found in native event tables\n", native[i].ni_papi_code);
01244                 continue;
01245             }
01246 
01247             // this native index is positive so there was a mask with the event, the ntv_idx identifies which native event to use
01248             ntv_evt = (struct native_event_t *)(&(pe_ctx->event_table->native_events[ntv_idx]));
01249             SUBDBG("ntv_evt: %p\n", ntv_evt);
01250 
01251             SUBDBG("i: %d, pe_ctx->event_table->num_native_events: %d\n", i, pe_ctx->event_table->num_native_events);
01252 
01253             // Move this events hardware config values and other attributes to the perf_events attribute structure
01254             memcpy (&pe_ctl->events[i].attr, &ntv_evt->attr, sizeof(perf_event_attr_t));
01255 
01256             // may need to update the attribute structure with information from event set level domain settings (values set by PAPI_set_domain)
01257             // only done if the event mask which controls each counting domain was not provided
01258 
01259             // get pointer to allocated name, will be NULL when adding preset events to event set
01260             char *aName = ntv_evt->allocated_name;
01261             if ((aName == NULL)  ||  (strstr(aName, ":u=") == NULL)) {
01262                 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));
01263                 pe_ctl->events[i].attr.exclude_user = !(pe_ctl->domain & PAPI_DOM_USER);
01264             }
01265             if ((aName == NULL)  ||  (strstr(aName, ":k=") == NULL)) {
01266                 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));
01267                 pe_ctl->events[i].attr.exclude_kernel = !(pe_ctl->domain & PAPI_DOM_KERNEL);
01268             }
01269 
01270             // libpfm4 supports mh (monitor host) and mg (monitor guest) event masks
01271             // perf_events supports exclude_hv and exclude_idle attributes
01272             // PAPI_set_domain supports PAPI_DOM_SUPERVISOR and PAPI_DOM_OTHER domain attributes
01273             // not sure how these perf_event attributes, and PAPI domain attributes relate to each other
01274             // if that can be figured out then there should probably be code here to set some perf_events attributes based on what was set in a PAPI_set_domain call
01275             // the code sample below is one possibility
01276 //          if (strstr(ntv_evt->allocated_name, ":mg=") == NULL) {
01277 //              SUBDBG("set exclude_hv attribute from eventset level domain flags, encode: %d, eventset: %d\n", pe_ctl->events[i].attr.exclude_hv, !(pe_ctl->domain & PAPI_DOM_SUPERVISOR));
01278 //              pe_ctl->events[i].attr.exclude_hv = !(pe_ctl->domain & PAPI_DOM_SUPERVISOR);
01279 //          }
01280 
01281 
01282             // set the cpu number provided with an event mask if there was one (will be -1 if mask not provided)
01283             pe_ctl->events[i].cpu = ntv_evt->cpu;
01284             // 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)
01285             if (pe_ctl->events[i].cpu == -1) {
01286                 pe_ctl->events[i].cpu = pe_ctl->cpu;
01287             }
01288       } else {
01289           // This case happens when called from _pe_set_overflow and _pe_ctl
01290           // Those callers put things directly into the pe_ctl structure so it is already set for the open call
01291       }
01292 
01293       // Copy the inherit flag into the attribute block that will be passed to the kernel
01294       pe_ctl->events[i].attr.inherit = pe_ctl->inherit;
01295 
01296       /* Set the position in the native structure */
01297       /* We just set up events linearly           */
01298       if ( native ) {
01299           native[i].ni_position = i;
01300           SUBDBG( "&native[%d]: %p, ni_papi_code: %#x, ni_event: %#x, ni_position: %d, ni_owners: %d\n",
01301             i, &(native[i]), native[i].ni_papi_code, native[i].ni_event, native[i].ni_position, native[i].ni_owners);
01302       }
01303    }
01304 
01305     if (count <= skipped_events) {
01306         SUBDBG("EXIT: No events to count, they all contained invalid umasks\n");
01307         return PAPI_ENOEVNT;
01308     }
01309 
01310    pe_ctl->num_events = count - skipped_events;
01311 
01312    /* actually open the events */
01313    /* (why is this a separate function?) */
01314    ret = open_pe_events( pe_ctx, pe_ctl );
01315    if ( ret != PAPI_OK ) {
01316       SUBDBG("EXIT: open_pe_events returned: %d\n", ret);
01317       /* Restore values ? */
01318       return ret;
01319    }
01320 
01321    SUBDBG( "EXIT: PAPI_OK\n" );
01322    return PAPI_OK;
01323 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _pe_write ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long *  from 
) [static]

Definition at line 888 of file perf_event.c.

00890 {
00891    ( void ) ctx;             /*unused */
00892    ( void ) ctl;             /*unused */
00893    ( void ) from;            /*unused */
00894    /*
00895     * Counters cannot be written.  Do we need to virtualize the
00896     * counters so that they can be written, or perhaps modify code so that
00897     * they can be written? FIXME ?
00898     */
00899 
00900     return PAPI_ENOSUPP;
00901 }

static int bug_format_group ( void   )  [static]

Definition at line 186 of file perf_event.c.

00186                        {
00187 
00188   if (_papi_os_info.os_version < LINUX_VERSION(2,6,34)) return 1;
00189 
00190   /* MIPS, as of version 3.1, does not support this properly */
00191 
00192 #if defined(__mips__)
00193   return 1;
00194 #endif
00195 
00196   return 0;
00197 
00198 }

Here is the caller graph for this function:

static int bug_sync_read ( void   )  [static]

Definition at line 206 of file perf_event.c.

00206                     {
00207 
00208   if (_papi_os_info.os_version < LINUX_VERSION(2,6,33)) return 1;
00209 
00210   return 0;
00211 
00212 }

Here is the caller graph for this function:

static int check_permissions ( unsigned long  tid,
unsigned int  cpu_num,
unsigned int  domain,
unsigned int  granularity,
unsigned int  multiplex,
unsigned int  inherit 
) [static]

Check if the current set of options is supported by

Definition at line 404 of file perf_event.c.

00410 {
00411    int ev_fd;
00412    struct perf_event_attr attr;
00413 
00414    long pid;
00415 
00416    /* clearing this will set a type of hardware and to count all domains */
00417    memset(&attr, '\0', sizeof(attr));
00418    attr.read_format = get_read_format(multiplex, inherit, 1);
00419 
00420    /* set the event id (config field) to instructios */
00421    /* (an event that should always exist)            */
00422    /* This was cycles but that is missing on Niagara */
00423    attr.config = PERF_COUNT_HW_INSTRUCTIONS;
00424 
00425    /* now set up domains this event set will be counting */
00426    if (!(domain & PAPI_DOM_SUPERVISOR)) {
00427       attr.exclude_hv = 1;
00428    }
00429    if (!(domain & PAPI_DOM_USER)) {
00430       attr.exclude_user = 1;
00431    }
00432    if (!(domain & PAPI_DOM_KERNEL)) {
00433       attr.exclude_kernel = 1;
00434    }
00435 
00436    if (granularity==PAPI_GRN_SYS) {
00437       pid = -1;
00438    } else {
00439       pid = tid;
00440    }
00441 
00442    SUBDBG("Calling sys_perf_event_open() from check_permissions\n");
00443 
00444    ev_fd = sys_perf_event_open( &attr, pid, cpu_num, -1, 0 );
00445    if ( ev_fd == -1 ) {
00446       SUBDBG("sys_perf_event_open returned error.  Linux says, %s", 
00447          strerror( errno ) );
00448       return map_perf_event_errors_to_papi(errno);
00449    }
00450 
00451    /* now close it, this was just to make sure we have permissions */
00452    /* to set these options                                         */
00453    close(ev_fd);
00454    return PAPI_OK;
00455 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_scheduability ( pe_context_t ctx,
pe_control_t ctl,
int  idx 
) [static]

Definition at line 473 of file perf_event.c.

00474 {
00475    int retval = 0, cnt = -1;
00476    ( void ) ctx;             /*unused */
00477    long long papi_pe_buffer[READ_BUFFER_SIZE];
00478    int i,group_leader_fd;
00479 
00480    /* If the kernel isn't tracking scheduability right       */
00481    /* Then we need to start/stop/read to force the event     */
00482    /* to be scheduled and see if an error condition happens. */
00483 
00484    /* get the proper fd to start */
00485    group_leader_fd=ctl->events[idx].group_leader_fd;
00486    if (group_leader_fd==-1) group_leader_fd=ctl->events[idx].event_fd;
00487 
00488    /* start the event */
00489    retval = ioctl( group_leader_fd, PERF_EVENT_IOC_ENABLE, NULL );
00490    if (retval == -1) {
00491       PAPIERROR("ioctl(PERF_EVENT_IOC_ENABLE) failed");
00492       return PAPI_ESYS;
00493    }
00494 
00495    /* stop the event */
00496    retval = ioctl(group_leader_fd, PERF_EVENT_IOC_DISABLE, NULL );
00497    if (retval == -1) {
00498       PAPIERROR( "ioctl(PERF_EVENT_IOC_DISABLE) failed" );
00499       return PAPI_ESYS;
00500    }
00501 
00502    /* See if a read returns any results */
00503    cnt = read( group_leader_fd, papi_pe_buffer, sizeof(papi_pe_buffer));
00504    if ( cnt == -1 ) {
00505       SUBDBG( "read returned an error!  Should never happen.\n" );
00506       return PAPI_ESYS;
00507    }
00508 
00509    if ( cnt == 0 ) {
00510       /* We read 0 bytes if we could not schedule the event */
00511       /* The kernel should have detected this at open       */
00512       /* but various bugs (including NMI watchdog)          */
00513       /* result in this behavior                            */
00514 
00515       return PAPI_ECNFLCT;
00516 
00517    } else {
00518 
00519       /* Reset all of the counters (opened so far) back to zero      */
00520       /* from the above brief enable/disable call pair.              */
00521 
00522       /* We have to reset all events because reset of group leader      */
00523       /* does not reset all.                                            */
00524       /* we assume that the events are being added one by one and that  */
00525       /* we do not need to reset higher events (doing so may reset ones */
00526       /* that have not been initialized yet.                            */
00527 
00528       /* Note... PERF_EVENT_IOC_RESET does not reset time running       */
00529       /* info if multiplexing, so we should avoid coming here if        */
00530       /* we are multiplexing the event.                                 */
00531       for( i = 0; i < idx; i++) {
00532      retval=ioctl( ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
00533      if (retval == -1) {
00534         PAPIERROR( "ioctl(PERF_EVENT_IOC_RESET) #%d/%d %d "
00535                "(fd %d)failed",
00536                i,ctl->num_events,idx,ctl->events[i].event_fd);
00537         return PAPI_ESYS;
00538      }
00539       }
00540    }
00541    return PAPI_OK;
00542 }

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 741 of file perf_event.c.

00742 {
00743    int i;
00744    int num_closed=0;
00745    int events_not_opened=0;
00746 
00747    /* should this be a more serious error? */
00748    if ( ctx->state & PERF_EVENTS_RUNNING ) {
00749       SUBDBG("Closing without stopping first\n");
00750    }
00751 
00752    /* Close child events first */
00753    for( i=0; i<ctl->num_events; i++ ) {
00754 
00755       if (ctl->events[i].event_opened) {
00756 
00757          if (ctl->events[i].group_leader_fd!=-1) {
00758             if ( ctl->events[i].mmap_buf ) {
00759            if ( munmap ( ctl->events[i].mmap_buf,
00760                      ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
00761               PAPIERROR( "munmap of fd = %d returned error: %s",
00762                  ctl->events[i].event_fd, strerror( errno ) );
00763               return PAPI_ESYS;
00764            }
00765         }
00766 
00767             if ( close( ctl->events[i].event_fd ) ) {
00768            PAPIERROR( "close of fd = %d returned error: %s",
00769                ctl->events[i].event_fd, strerror( errno ) );
00770            return PAPI_ESYS;
00771         } else {
00772            num_closed++;
00773         }
00774         ctl->events[i].event_opened=0;
00775      }
00776       }
00777       else {
00778     events_not_opened++;
00779       }
00780    }
00781 
00782    /* Close the group leaders last */
00783    for( i=0; i<ctl->num_events; i++ ) {
00784 
00785       if (ctl->events[i].event_opened) {
00786 
00787          if (ctl->events[i].group_leader_fd==-1) {
00788             if ( ctl->events[i].mmap_buf ) {
00789            if ( munmap ( ctl->events[i].mmap_buf,
00790                      ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
00791               PAPIERROR( "munmap of fd = %d returned error: %s",
00792                  ctl->events[i].event_fd, strerror( errno ) );
00793               return PAPI_ESYS;
00794            }
00795         }
00796 
00797 
00798             if ( close( ctl->events[i].event_fd ) ) {
00799            PAPIERROR( "close of fd = %d returned error: %s",
00800                ctl->events[i].event_fd, strerror( errno ) );
00801            return PAPI_ESYS;
00802         } else {
00803            num_closed++;
00804         }
00805         ctl->events[i].event_opened=0;
00806      }
00807       }
00808    }
00809 
00810 
00811    if (ctl->num_events!=num_closed) {
00812       if (ctl->num_events!=(num_closed+events_not_opened)) {
00813          PAPIERROR("Didn't close all events: "
00814            "Closed %d Not Opened: %d Expected %d",
00815            num_closed,events_not_opened,ctl->num_events);
00816          return PAPI_EBUG;
00817       }
00818    }
00819 
00820    ctl->num_events=0;
00821 
00822    ctx->state &= ~PERF_EVENTS_OPENED;
00823 
00824    return PAPI_OK;
00825 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int fcntl_setown_fd ( int  fd  )  [static]

Definition at line 220 of file perf_event.c.

00220                         {
00221 
00222    int ret;
00223    struct f_owner_ex fown_ex;
00224 
00225       /* F_SETOWN_EX is not available until 2.6.32 */
00226    if (_papi_os_info.os_version < LINUX_VERSION(2,6,32)) {
00227 
00228       /* get ownership of the descriptor */
00229       ret = fcntl( fd, F_SETOWN, mygettid(  ) );
00230       if ( ret == -1 ) {
00231      PAPIERROR( "cannot fcntl(F_SETOWN) on %d: %s", fd, strerror(errno) );
00232      return PAPI_ESYS;
00233       }
00234    }
00235    else {
00236       /* set ownership of the descriptor */
00237       fown_ex.type = F_OWNER_TID;
00238       fown_ex.pid  = mygettid();
00239       ret = fcntl(fd, F_SETOWN_EX, (unsigned long)&fown_ex );
00240 
00241       if ( ret == -1 ) {
00242      PAPIERROR( "cannot fcntl(F_SETOWN_EX) on %d: %s",
00243             fd, strerror( errno ) );
00244      return PAPI_ESYS;
00245       }
00246    }
00247    return PAPI_OK;
00248 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int find_profile_index ( EventSetInfo_t ESI,
int  evt_idx,
int *  flags,
unsigned int *  native_index,
int *  profile_index 
) [static]

Definition at line 1871 of file perf_event.c.

01873 {
01874   int pos, esi_index, count;
01875 
01876   for ( count = 0; count < ESI->profile.event_counter; count++ ) {
01877     esi_index = ESI->profile.EventIndex[count];
01878     pos = ESI->EventInfoArray[esi_index].pos[0];
01879                 
01880     if ( pos == evt_idx ) {
01881       *profile_index = count;
01882           *native_index = ESI->NativeInfoArray[pos].ni_event & 
01883         PAPI_NATIVE_AND_MASK;
01884           *flags = ESI->profile.flags;
01885           SUBDBG( "Native event %d is at profile index %d, flags %d\n",
01886                   *native_index, *profile_index, *flags );
01887           return PAPI_OK;
01888     }
01889   }
01890   PAPIERROR( "wrong count: %d vs. ESI->profile.event_counter %d", count,
01891          ESI->profile.event_counter );
01892   return PAPI_EBUG;
01893 }

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 254 of file perf_event.c.

00257 {
00258    unsigned int format = 0;
00259 
00260    /* if we need read format options for multiplexing, add them now */
00261    if (multiplex) {
00262       format |= PERF_FORMAT_TOTAL_TIME_ENABLED;
00263       format |= PERF_FORMAT_TOTAL_TIME_RUNNING;
00264    }
00265 
00266    /* if our kernel supports it and we are not using inherit, */
00267    /* add the group read options                              */
00268    if ( (!bug_format_group()) && !inherit) {
00269       if (format_group) {
00270      format |= PERF_FORMAT_GROUP;
00271       }
00272    }
00273 
00274    SUBDBG("multiplex: %d, inherit: %d, group_leader: %d, format: %#x\n",
00275       multiplex, inherit, format_group, format);
00276 
00277    return format;
00278 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int map_perf_event_errors_to_papi ( int  perf_event_error  )  [static]

Definition at line 355 of file perf_event.c.

00355                                                                {
00356 
00357    int ret;
00358 
00359    /* These mappings are approximate.
00360       EINVAL in particular can mean lots of different things */
00361    switch(perf_event_error) {
00362       case EPERM:
00363       case EACCES:
00364            ret = PAPI_EPERM;
00365        break;
00366       case ENODEV:
00367       case EOPNOTSUPP:
00368        ret = PAPI_ENOSUPP;
00369            break;
00370       case ENOENT:
00371        ret = PAPI_ENOEVNT;
00372            break;
00373       case ENOSYS:
00374       case EAGAIN:
00375       case EBUSY:
00376       case E2BIG:   /* Only happens if attr is the wrong size somehow */
00377       case EBADF:   /* We are attempting to group with an invalid file descriptor */
00378        ret = PAPI_ESYS;
00379        break;
00380       case ENOMEM:
00381        ret = PAPI_ENOMEM;
00382        break;
00383       case EMFILE:  /* Out of file descriptors.  Typically max out at 1024 */
00384            ret = PAPI_ECOUNT;
00385            break;
00386       case EINVAL:
00387       default:
00388        ret = PAPI_EINVAL;
00389            break;
00390    }
00391    return ret;
00392 }

Here is the caller graph for this function:

static void mmap_read ( int  cidx,
ThreadInfo_t **  thr,
pe_event_info_t pe,
int  profile_index 
) [static]

Definition at line 1800 of file perf_event.c.

01802 {
01803   uint64_t head = mmap_read_head( pe );
01804   uint64_t old = pe->tail;
01805   unsigned char *data = ((unsigned char*)pe->mmap_buf) + getpagesize(  );
01806   int diff;
01807 
01808   diff = head - old;
01809   if ( diff < 0 ) {
01810     SUBDBG( "WARNING: failed to keep up with mmap data. head = %" PRIu64
01811         ",  tail = %" PRIu64 ". Discarding samples.\n", head, old );
01812     /* head points to a known good entry, start there. */
01813     old = head;
01814   }
01815 
01816   for( ; old != head; ) {
01817     perf_sample_event_t *event = ( perf_sample_event_t * ) 
01818       & data[old & pe->mask];
01819     perf_sample_event_t event_copy;
01820     size_t size = event->header.size;
01821 
01822     /* Event straddles the mmap boundary -- header should always */
01823     /* be inside due to u64 alignment of output.                 */
01824     if ( ( old & pe->mask ) + size != ( ( old + size ) & pe->mask ) ) {
01825       uint64_t offset = old;
01826       uint64_t len = min( sizeof ( *event ), size ), cpy;
01827       void *dst = &event_copy;
01828 
01829       do {
01830     cpy = min( pe->mask + 1 - ( offset & pe->mask ), len );
01831     memcpy( dst, &data[offset & pe->mask], cpy );
01832     offset += cpy;
01833     dst = ((unsigned char*)dst) + cpy;
01834     len -= cpy;
01835       } while ( len );
01836 
01837       event = &event_copy;
01838     }
01839     old += size;
01840 
01841     SUBDBG( "event->type = %08x\n", event->header.type );
01842     SUBDBG( "event->size = %d\n", event->header.size );
01843 
01844     switch ( event->header.type ) {
01845     case PERF_RECORD_SAMPLE:
01846       _papi_hwi_dispatch_profile( ( *thr )->running_eventset[cidx],
01847                   ( caddr_t ) ( unsigned long ) event->ip.ip, 
01848                   0, profile_index );
01849       break;
01850 
01851     case PERF_RECORD_LOST:
01852       SUBDBG( "Warning: because of a mmap buffer overrun, %" PRId64
01853                       " events were lost.\n"
01854                       "Loss was recorded when counter id %#"PRIx64 
01855           " overflowed.\n", event->lost.lost, event->lost.id );
01856       break;
01857 
01858     default:
01859       SUBDBG( "Error: unexpected header type - %d\n",
01860           event->header.type );
01861       break;
01862     }
01863   }
01864 
01865   pe->tail = old;
01866   mmap_write_tail( pe, old );
01867 }

Here is the call graph for this function:

Here is the caller graph for this function:

static uint64_t mmap_read_head ( pe_event_info_t pe  )  [static]

Definition at line 1755 of file perf_event.c.

01756 {
01757   struct perf_event_mmap_page *pc = pe->mmap_buf;
01758   int head;
01759 
01760   if ( pc == NULL ) {
01761     PAPIERROR( "perf_event_mmap_page is NULL" );
01762     return 0;
01763   }
01764 
01765   head = pc->data_head;
01766   rmb(  );
01767 
01768   return head;
01769 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void mmap_write_tail ( pe_event_info_t pe,
uint64_t  tail 
) [static]

Definition at line 1772 of file perf_event.c.

01773 {
01774   struct perf_event_mmap_page *pc = pe->mmap_buf;
01775 
01776   /* ensure all reads are done before we write the tail out. */
01777   pc->data_tail = tail;
01778 }

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 616 of file perf_event.c.

00617 {
00618 
00619    int i, ret = PAPI_OK;
00620    long pid;
00621 
00622    if (ctl->granularity==PAPI_GRN_SYS) {
00623       pid = -1;
00624    }
00625    else {
00626       pid = ctl->tid;
00627    }
00628 
00629    for( i = 0; i < ctl->num_events; i++ ) {
00630 
00631       ctl->events[i].event_opened=0;
00632 
00633       /* set up the attr structure.  We don't set up all fields here */
00634       /* as some have already been set up previously.                */
00635 
00636       /* group leader (event 0) is special                */
00637       /* If we're multiplexed, everyone is a group leader */
00638       if (( i == 0 ) || (ctl->multiplexed)) {
00639          ctl->events[i].attr.pinned = !ctl->multiplexed;
00640      ctl->events[i].attr.disabled = 1;
00641      ctl->events[i].group_leader_fd=-1;
00642          ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed, 
00643                                ctl->inherit, 
00644                                !ctl->multiplexed );
00645       } else {
00646      ctl->events[i].attr.pinned=0;
00647      ctl->events[i].attr.disabled = 0;
00648      ctl->events[i].group_leader_fd=ctl->events[0].event_fd;
00649          ctl->events[i].attr.read_format = get_read_format(ctl->multiplexed, 
00650                                ctl->inherit, 
00651                                0 );
00652       }
00653 
00654 
00655       /* try to open */
00656       ctl->events[i].event_fd = sys_perf_event_open( &ctl->events[i].attr, 
00657                              pid,
00658                              ctl->events[i].cpu,
00659                    ctl->events[i].group_leader_fd,
00660                              0 /* flags */
00661                              );
00662 
00663             /* Try to match Linux errors to PAPI errors */
00664       if ( ctl->events[i].event_fd == -1 ) {
00665      SUBDBG("sys_perf_event_open returned error on event #%d."
00666         "  Error: %s\n",
00667         i, strerror( errno ) );
00668          ret=map_perf_event_errors_to_papi(errno);
00669 
00670      goto open_pe_cleanup;
00671       }
00672 
00673       SUBDBG ("sys_perf_event_open: tid: %ld, cpu_num: %d,"
00674               " group_leader/fd: %d, event_fd: %d,"
00675               " read_format: %"PRIu64"\n",
00676           pid, ctl->events[i].cpu, ctl->events[i].group_leader_fd,
00677           ctl->events[i].event_fd, ctl->events[i].attr.read_format);
00678 
00679 
00680       /* in many situations the kernel will indicate we opened fine */
00681       /* yet things will fail later.  So we need to double check    */
00682       /* we actually can use the events we've set up.               */
00683 
00684       /* This is not necessary if we are multiplexing, and in fact */
00685       /* we cannot do this properly if multiplexed because         */
00686       /* PERF_EVENT_IOC_RESET does not reset the time running info */
00687       if (!ctl->multiplexed) {
00688      ret = check_scheduability( ctx, ctl, i );
00689 
00690          if ( ret != PAPI_OK ) {
00691         /* the last event did open, so we need to bump the counter */
00692         /* before doing the cleanup                                */
00693         i++;
00694             goto open_pe_cleanup;
00695      }
00696       }
00697       ctl->events[i].event_opened=1;
00698    }
00699 
00700    /* Now that we've successfully opened all of the events, do whatever  */
00701    /* "tune-up" is needed to attach the mmap'd buffers, signal handlers, */
00702    /* and so on.                                                         */
00703    for ( i = 0; i < ctl->num_events; i++ ) {
00704 
00705       /* If sampling is enabled, hook up signal handler */
00706       if ((ctl->events[i].attr.sample_period)  &&  (ctl->events[i].nr_mmap_pages > 0)) {
00707      ret = tune_up_fd( ctl, i );
00708      if ( ret != PAPI_OK ) {
00709         /* All of the fds are open, so we need to clean up all of them */
00710         i = ctl->num_events;
00711         goto open_pe_cleanup;
00712      }
00713       } else {
00714      /* Make sure this is NULL so close_pe_events works right */
00715      ctl->events[i].mmap_buf = NULL;
00716       }
00717    }
00718 
00719    /* Set num_evts only if completely successful */
00720    ctx->state |= PERF_EVENTS_OPENED;
00721 
00722    return PAPI_OK;
00723 
00724 open_pe_cleanup:
00725    /* We encountered an error, close up the fds we successfully opened.  */
00726    /* We go backward in an attempt to close group leaders last, although */
00727    /* That's probably not strictly necessary.                            */
00728    while ( i > 0 ) {
00729       i--;
00730       if (ctl->events[i].event_fd>=0) {
00731      close( ctl->events[i].event_fd );
00732      ctl->events[i].event_opened=0;
00733       }
00734    }
00735 
00736    return ret;
00737 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int pe_vendor_fixups ( papi_vector_t vector  )  [static]

Definition at line 124 of file perf_event.c.

00125 {
00126      /* powerpc */
00127      /* On IBM and Power6 Machines default domain should include supervisor */
00128   if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_IBM ) {
00129      vector->cmp_info.available_domains |=
00130                   PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
00131      if (strcmp(_papi_hwi_system_info.hw_info.model_string, "POWER6" ) == 0 ) {
00132         vector->cmp_info.default_domain =
00133                   PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
00134      }
00135   }
00136 
00137   if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_MIPS ) {
00138      vector->cmp_info.available_domains |= PAPI_DOM_KERNEL;
00139   }
00140 
00141   if ((_papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL) ||
00142       (_papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_AMD)) {
00143      vector->cmp_info.fast_real_timer = 1;
00144   }
00145 
00146     /* ARM */
00147     if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_ARM) {
00148 
00149         /* Some ARMv7 and earlier could not measure */
00150         /* KERNEL and USER separately.          */
00151 
00152         /* Whitelist CortexA7 and CortexA15     */
00153         /* There might be more              */
00154 
00155         if ((_papi_hwi_system_info.hw_info.cpuid_family < 8) &&
00156             (_papi_hwi_system_info.hw_info.cpuid_model!=0xc07) &&
00157             (_papi_hwi_system_info.hw_info.cpuid_model!=0xc0f)) {
00158 
00159             vector->cmp_info.available_domains |=
00160                 PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
00161             vector->cmp_info.default_domain =
00162                 PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
00163         }
00164     }
00165 
00166     /* CRAY */
00167     if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_CRAY ) {
00168         vector->cmp_info.available_domains |= PAPI_DOM_OTHER;
00169     }
00170 
00171     return PAPI_OK;
00172 }

Here is the caller graph for this function:

static int process_smpl_buf ( int  evt_idx,
ThreadInfo_t **  thr,
int  cidx 
) [static]

Definition at line 1899 of file perf_event.c.

01900 {
01901   int ret, flags, profile_index;
01902   unsigned native_index;
01903   pe_control_t *ctl;
01904 
01905   ret = find_profile_index( ( *thr )->running_eventset[cidx], evt_idx, 
01906                 &flags, &native_index, &profile_index );
01907   if ( ret != PAPI_OK ) {
01908     return ret;
01909   }
01910 
01911   ctl= (*thr)->running_eventset[cidx]->ctl_state;
01912 
01913   mmap_read( cidx, thr, 
01914          &(ctl->events[evt_idx]),
01915          profile_index );
01916 
01917   return PAPI_OK;
01918 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int processor_supported ( int  vendor,
int  family 
) [static]

Definition at line 110 of file perf_event.c.

00110                                             {
00111 
00112    /* Error out if kernel too early to support p4 */
00113    if (( vendor == PAPI_VENDOR_INTEL ) && (family == 15)) {
00114       if (_papi_os_info.os_version < LINUX_VERSION(2,6,35)) {
00115          PAPIERROR("Pentium 4 not supported on kernels before 2.6.35");
00116          return PAPI_ENOSUPP;
00117       }
00118    }
00119    return PAPI_OK;
00120 }

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 304 of file perf_event.c.

00306 {
00307     int ret;
00308 
00309    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);
00310    SUBDBG("   type: %d\n",hw_event->type);
00311    SUBDBG("   size: %d\n",hw_event->size);
00312    SUBDBG("   config: %"PRIx64" (%"PRIu64")\n",hw_event->config, hw_event->config);
00313    SUBDBG("   sample_period: %"PRIu64"\n",hw_event->sample_period);
00314    SUBDBG("   sample_type: %"PRIu64"\n",hw_event->sample_type);
00315    SUBDBG("   read_format: %"PRIu64"\n",hw_event->read_format);
00316    SUBDBG("   disabled: %d\n",hw_event->disabled);
00317    SUBDBG("   inherit: %d\n",hw_event->inherit);
00318    SUBDBG("   pinned: %d\n",hw_event->pinned);
00319    SUBDBG("   exclusive: %d\n",hw_event->exclusive);
00320    SUBDBG("   exclude_user: %d\n",hw_event->exclude_user);
00321    SUBDBG("   exclude_kernel: %d\n",hw_event->exclude_kernel);
00322    SUBDBG("   exclude_hv: %d\n",hw_event->exclude_hv);
00323    SUBDBG("   exclude_idle: %d\n",hw_event->exclude_idle);
00324    SUBDBG("   mmap: %d\n",hw_event->mmap);
00325    SUBDBG("   comm: %d\n",hw_event->comm);
00326    SUBDBG("   freq: %d\n",hw_event->freq);
00327    SUBDBG("   inherit_stat: %d\n",hw_event->inherit_stat);
00328    SUBDBG("   enable_on_exec: %d\n",hw_event->enable_on_exec);
00329    SUBDBG("   task: %d\n",hw_event->task);
00330    SUBDBG("   watermark: %d\n",hw_event->watermark);
00331    SUBDBG("   precise_ip: %d\n",hw_event->precise_ip);
00332    SUBDBG("   mmap_data: %d\n",hw_event->mmap_data);
00333    SUBDBG("   sample_id_all: %d\n",hw_event->sample_id_all);
00334    SUBDBG("   exclude_host: %d\n",hw_event->exclude_host);
00335    SUBDBG("   exclude_guest: %d\n",hw_event->exclude_guest);
00336    SUBDBG("   exclude_callchain_kernel: %d\n",hw_event->exclude_callchain_kernel);
00337    SUBDBG("   exclude_callchain_user: %d\n",hw_event->exclude_callchain_user);
00338    SUBDBG("   wakeup_events: %"PRIx32" (%"PRIu32")\n", hw_event->wakeup_events, hw_event->wakeup_events);
00339    SUBDBG("   bp_type: %"PRIx32" (%"PRIu32")\n", hw_event->bp_type, hw_event->bp_type);
00340    SUBDBG("   config1: %"PRIx64" (%"PRIu64")\n", hw_event->config1, hw_event->config1);
00341    SUBDBG("   config2: %"PRIx64" (%"PRIu64")\n", hw_event->config2, hw_event->config2);
00342    SUBDBG("   branch_sample_type: %"PRIx64" (%"PRIu64")\n", hw_event->branch_sample_type, hw_event->branch_sample_type);
00343    SUBDBG("   sample_regs_user: %"PRIx64" (%"PRIu64")\n", hw_event->sample_regs_user, hw_event->sample_regs_user);
00344    SUBDBG("   sample_stack_user: %"PRIx32" (%"PRIu32")\n", hw_event->sample_stack_user, hw_event->sample_stack_user);
00345 
00346     ret =
00347         syscall( __NR_perf_event_open, hw_event, pid, cpu, group_fd, flags );
00348     SUBDBG("Returned %d %d %s\n",ret,
00349            ret<0?errno:0,
00350            ret<0?strerror(errno):" ");
00351     return ret;
00352 }

Here is the caller graph for this function:

static int tune_up_fd ( pe_control_t ctl,
int  evt_idx 
) [static]

Definition at line 548 of file perf_event.c.

00549 {
00550    int ret;
00551    void *buf_addr;
00552    int fd = ctl->events[evt_idx].event_fd;
00553 
00554    /* Register that we would like a SIGIO notification when a mmap'd page */
00555    /* becomes full.                                                       */
00556    ret = fcntl( fd, F_SETFL, O_ASYNC | O_NONBLOCK );
00557    if ( ret ) {
00558       PAPIERROR ( "fcntl(%d, F_SETFL, O_ASYNC | O_NONBLOCK) "
00559           "returned error: %s", fd, strerror( errno ) );
00560       return PAPI_ESYS;
00561    }
00562 
00563    /* Set the F_SETOWN_EX flag on the fd.                          */
00564    /* This affects which thread an overflow signal gets sent to.   */
00565    ret=fcntl_setown_fd(fd);
00566    if (ret!=PAPI_OK) return ret;
00567 
00568    /* Set FD_CLOEXEC.  Otherwise if we do an exec with an overflow */
00569    /* running, the overflow handler will continue into the exec()'d*/
00570    /* process and kill it because no signal handler is set up.     */
00571    ret=fcntl(fd, F_SETFD, FD_CLOEXEC);
00572    if (ret) {
00573       return PAPI_ESYS;
00574    }
00575 
00576    /* when you explicitely declare that you want a particular signal,  */
00577    /* even with you use the default signal, the kernel will send more  */
00578    /* information concerning the event to the signal handler.          */
00579    /*                                                                  */
00580    /* In particular, it will send the file descriptor from which the   */
00581    /* event is originating which can be quite useful when monitoring   */
00582    /* multiple tasks from a single thread.                             */
00583    ret = fcntl( fd, F_SETSIG, ctl->overflow_signal );
00584    if ( ret == -1 ) {
00585       PAPIERROR( "cannot fcntl(F_SETSIG,%d) on %d: %s",
00586          ctl->overflow_signal, fd,
00587          strerror( errno ) );
00588       return PAPI_ESYS;
00589    }
00590 
00591    /* mmap() the sample buffer */
00592    buf_addr = mmap( NULL, ctl->events[evt_idx].nr_mmap_pages * getpagesize(),
00593             PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
00594    if ( buf_addr == MAP_FAILED ) {
00595       PAPIERROR( "mmap(NULL,%d,%d,%d,%d,0): %s",
00596          ctl->events[evt_idx].nr_mmap_pages * getpagesize(  ), 
00597          PROT_READ, MAP_SHARED, fd, strerror( errno ) );
00598       return ( PAPI_ESYS );
00599    }
00600 
00601    SUBDBG( "Sample buffer for fd %d is located at %p\n", fd, buf_addr );
00602 
00603    /* Set up the mmap buffer and its associated helpers */
00604    ctl->events[evt_idx].mmap_buf = (struct perf_counter_mmap_page *) buf_addr;
00605    ctl->events[evt_idx].tail = 0;
00606    ctl->events[evt_idx].mask = ( ctl->events[evt_idx].nr_mmap_pages - 1 ) *
00607                                getpagesize() - 1;
00608 
00609    return PAPI_OK;
00610 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 62 of file perf_event.c.

int our_cidx [static]

Definition at line 76 of file perf_event.c.

Definition at line 75 of file perf_event.c.


Generated on 8 Sep 2016 for PAPI by  doxygen 1.6.1