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

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_check_scheduability (void)
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)
int _pe_shutdown_thread (hwd_context_t *ctx)
int _pe_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _pe_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
int _pe_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
int _pe_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _pe_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _pe_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
int _pe_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int _pe_init_thread (hwd_context_t *hwd_ctx)
int _pe_init_control_state (hwd_control_state_t *ctl)
static int _pe_detect_rdpmc (int default_domain)
int _pe_init_component (int cidx)
int _pe_shutdown_component (void)
int _pe_ntv_enum_events (unsigned int *PapiEventCode, int modifier)
int _pe_ntv_name_to_code (char *name, unsigned int *event_code)
int _pe_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
int _pe_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len)
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)
void _pe_dispatch_timer (int n, hwd_siginfo_t *info, void *uc)
int _pe_stop_profiling (ThreadInfo_t *thread, EventSetInfo_t *ESI)
int _pe_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
int _pe_set_profile (EventSetInfo_t *ESI, int EventIndex, int threshold)

Variables

int nmi_watchdog_active
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 92 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 484 of file perf_event.c.

#define WAKEUP_COUNTER_OVERFLOW   0

Definition at line 78 of file perf_event.c.

#define WAKEUP_MODE_COUNTER_OVERFLOW   0

Definition at line 81 of file perf_event.c.

#define WAKEUP_MODE_PROFILING   1

Definition at line 82 of file perf_event.c.

#define WAKEUP_PROFILING   -1

Definition at line 79 of file perf_event.c.


Function Documentation

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

Definition at line 1351 of file perf_event.c.

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

Here is the call graph for this function:

static int _pe_detect_rdpmc ( int  default_domain  )  [static]

Definition at line 1566 of file perf_event.c.

01566                                                 {
01567 
01568   struct perf_event_attr pe;
01569   int fd,rdpmc_exists=1;
01570   void *addr;
01571   struct perf_event_mmap_page *our_mmap;
01572 
01573   /* Create a fake instructions event so we can read a mmap page */
01574   memset(&pe,0,sizeof(struct perf_event_attr));
01575 
01576   pe.type=PERF_TYPE_HARDWARE;
01577   pe.size=sizeof(struct perf_event_attr);
01578   pe.config=PERF_COUNT_HW_INSTRUCTIONS;
01579 
01580   /* There should probably be a helper function to handle this      */
01581   /* we break on some ARM because there is no support for excluding */
01582   /* kernel.                                                        */
01583   if (default_domain & PAPI_DOM_KERNEL ) {
01584   }
01585   else {
01586     pe.exclude_kernel=1;
01587   }
01588   fd=sys_perf_event_open(&pe,0,-1,-1,0);
01589   if (fd<0) {
01590     return PAPI_ESYS;
01591   }
01592 
01593   /* create the mmap page */
01594   addr=mmap(NULL, 4096, PROT_READ, MAP_SHARED,fd,0);
01595   if (addr == (void *)(-1)) {
01596     close(fd);
01597     return PAPI_ESYS;
01598   }
01599 
01600   /* get the rdpmc info */
01601   our_mmap=(struct perf_event_mmap_page *)addr;
01602   if (our_mmap->cap_usr_rdpmc==0) {
01603     rdpmc_exists=0;
01604   }
01605 
01606   /* close the fake event */
01607   munmap(addr,4096);
01608   close(fd);
01609 
01610   return rdpmc_exists;
01611 
01612 }

Here is the call graph for this function:

Here is the caller graph for this function:

void _pe_dispatch_timer ( int  n,
hwd_siginfo_t info,
void *  uc 
)

Definition at line 1951 of file perf_event.c.

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

Here is the call graph for this function:

int _pe_init_component ( int  cidx  ) 

Definition at line 1617 of file perf_event.c.

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

Here is the call graph for this function:

int _pe_init_control_state ( hwd_control_state_t ctl  ) 

Definition at line 1541 of file perf_event.c.

01542 {
01543   pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01544 
01545   /* clear the contents */
01546   memset( pe_ctl, 0, sizeof ( pe_control_t ) );
01547 
01548   /* Set the domain */
01549   _pe_set_domain( ctl, _perf_event_vector.cmp_info.default_domain );    
01550 
01551   /* default granularity */
01552   pe_ctl->granularity= _perf_event_vector.cmp_info.default_granularity;
01553 
01554   /* overflow signal */
01555   pe_ctl->overflow_signal=_perf_event_vector.cmp_info.hardware_intr_sig;
01556 
01557   pe_ctl->cidx=our_cidx;
01558 
01559   /* Set cpu number in the control block to show events */
01560   /* are not tied to specific cpu                       */
01561   pe_ctl->cpu = -1;
01562   return PAPI_OK;
01563 }

Here is the call graph for this function:

int _pe_init_thread ( hwd_context_t hwd_ctx  ) 

Definition at line 1525 of file perf_event.c.

01526 {
01527 
01528   pe_context_t *pe_ctx = ( pe_context_t *) hwd_ctx;
01529 
01530   /* clear the context structure and mark as initialized */
01531   memset( pe_ctx, 0, sizeof ( pe_context_t ) );
01532   pe_ctx->initialized=1;
01533   pe_ctx->event_table=&perf_native_event_table;
01534   pe_ctx->cidx=our_cidx;
01535 
01536   return PAPI_OK;
01537 }

int _pe_libpfm4_get_cidx ( void   ) 

Definition at line 71 of file perf_event.c.

00071                        {
00072     return our_cidx;
00073 }

Here is the caller graph for this function:

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

Definition at line 1761 of file perf_event.c.

01762                                                       {
01763 
01764    return _pe_libpfm4_ntv_code_to_descr(EventCode,ntv_descr,len,
01765                                           &perf_native_event_table);
01766 }

Here is the call graph for this function:

int _pe_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)

Definition at line 1769 of file perf_event.c.

01770                                                    {
01771 
01772   return _pe_libpfm4_ntv_code_to_info(EventCode, info,
01773                                         &perf_native_event_table);
01774 }

Here is the call graph for this function:

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

Definition at line 1753 of file perf_event.c.

01754                                                    {
01755    return _pe_libpfm4_ntv_code_to_name(EventCode,
01756                                          ntv_name, len, 
01757                     &perf_native_event_table);
01758 }

Here is the call graph for this function:

int _pe_ntv_enum_events ( unsigned int *  PapiEventCode,
int  modifier 
)

Definition at line 1740 of file perf_event.c.

01741 {
01742   return _pe_libpfm4_ntv_enum_events(PapiEventCode, modifier,
01743                                        &perf_native_event_table);
01744 }

Here is the call graph for this function:

int _pe_ntv_name_to_code ( char *  name,
unsigned int *  event_code 
)

Definition at line 1747 of file perf_event.c.

01747                                                             {
01748   return _pe_libpfm4_ntv_name_to_code(name,event_code,
01749                                         &perf_native_event_table);
01750 }

Here is the call graph for this function:

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

Definition at line 942 of file perf_event.c.

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

Here is the call graph for this function:

int _pe_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 887 of file perf_event.c.

00888 {
00889    int i, ret;
00890    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
00891 
00892    ( void ) ctx;             /*unused */
00893 
00894    /* We need to reset all of the events, not just the group leaders */
00895    for( i = 0; i < pe_ctl->num_events; i++ ) {
00896       ret = ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_RESET, NULL );
00897       if ( ret == -1 ) {
00898      PAPIERROR("ioctl(%d, PERF_EVENT_IOC_RESET, NULL) "
00899            "returned error, Linux says: %s",
00900            pe_ctl->events[i].event_fd, strerror( errno ) );
00901      return PAPI_ESYS;
00902       }
00903    }
00904 
00905    return PAPI_OK;
00906 }

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

00863 {
00864    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
00865 
00866    SUBDBG("old control domain %d, new domain %d\n", pe_ctl->domain,domain);
00867    pe_ctl->domain = domain;
00868    return PAPI_OK;
00869 }

Here is the caller graph for this function:

int _pe_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)

Definition at line 2125 of file perf_event.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_set_profile ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)

Definition at line 2231 of file perf_event.c.

02232 {
02233   int ret;
02234   int evt_idx;
02235   pe_control_t *ctl = ( pe_control_t *) ( ESI->ctl_state );
02236 
02237   /* Since you can't profile on a derived event, the event is always the */
02238   /* first and only event in the native event list.                      */
02239   evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
02240 
02241   if ( threshold == 0 ) {
02242     SUBDBG( "MUNMAP(%p,%"PRIu64")\n", ctl->events[evt_idx].mmap_buf,
02243         ( uint64_t ) ctl->events[evt_idx].nr_mmap_pages *
02244         getpagesize(  ) );
02245 
02246     if ( ctl->events[evt_idx].mmap_buf ) {
02247       munmap( ctl->events[evt_idx].mmap_buf,
02248           ctl->events[evt_idx].nr_mmap_pages * getpagesize() );
02249     }
02250     ctl->events[evt_idx].mmap_buf = NULL;
02251     ctl->events[evt_idx].nr_mmap_pages = 0;
02252     ctl->events[evt_idx].attr.sample_type &= ~PERF_SAMPLE_IP;
02253     ret = _pe_set_overflow( ESI, EventIndex, threshold );
02254     /* ??? #warning "This should be handled somewhere else" */
02255     ESI->state &= ~( PAPI_OVERFLOWING );
02256     ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
02257 
02258     return ret;
02259   }
02260 
02261   /* Look up the native event code */
02262   if ( ESI->profile.flags & (PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR)) {
02263     /* Not supported yet... */
02264 
02265     return PAPI_ENOSUPP;
02266   }
02267   if ( ESI->profile.flags & PAPI_PROFIL_RANDOM ) {
02268     /* This requires an ability to randomly alter the sample_period within */
02269     /* a given range.  Kernel does not have this ability. FIXME            */
02270     return PAPI_ENOSUPP;
02271   }
02272 
02273   /* Just a guess at how many pages would make this relatively efficient.  */
02274   /* Note that it's "1 +" because of the need for a control page, and the  */
02275   /* number following the "+" must be a power of 2 (1, 4, 8, 16, etc) or   */
02276   /* zero.  This is required to optimize dealing with circular buffer      */
02277   /* wrapping of the mapped pages.                                         */
02278 
02279   ctl->events[evt_idx].nr_mmap_pages = (1+8);
02280   ctl->events[evt_idx].attr.sample_type |= PERF_SAMPLE_IP;
02281 
02282   ret = _pe_set_overflow( ESI, EventIndex, threshold );
02283   if ( ret != PAPI_OK ) return ret;
02284 
02285   return PAPI_OK;
02286 }

Here is the call graph for this function:

int _pe_shutdown_component ( void   ) 

Definition at line 1725 of file perf_event.c.

01725                                {
01726 
01727   /* deallocate our event table */
01728   _pe_libpfm4_shutdown(&_perf_event_vector, &perf_native_event_table);
01729 
01730   /* Shutdown libpfm4 */
01731   _papi_libpfm4_shutdown();
01732 
01733   return PAPI_OK;
01734 }

Here is the call graph for this function:

int _pe_shutdown_thread ( hwd_context_t ctx  ) 

Definition at line 873 of file perf_event.c.

00874 {
00875     pe_context_t *pe_ctx = ( pe_context_t *) ctx;
00876 
00877     pe_ctx->initialized=0;
00878 
00879     return PAPI_OK;
00880 }

int _pe_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 1144 of file perf_event.c.

01145 {
01146    int ret;
01147    int i;
01148    int did_something = 0;
01149    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
01150    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01151 
01152    /* Reset the counters first.  Is this necessary? */
01153    ret = _pe_reset( pe_ctx, pe_ctl );
01154    if ( ret ) {
01155       return ret;
01156    }
01157 
01158    /* Enable all of the group leaders                */
01159    /* All group leaders have a group_leader_fd of -1 */
01160    for( i = 0; i < pe_ctl->num_events; i++ ) {
01161       if (pe_ctl->events[i].group_leader_fd == -1) {
01162      SUBDBG("ioctl(enable): fd: %d\n", pe_ctl->events[i].event_fd);
01163      ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_ENABLE, NULL) ;
01164 
01165      /* ioctls always return -1 on failure */
01166          if (ret == -1) {
01167             PAPIERROR("ioctl(PERF_EVENT_IOC_ENABLE) failed");
01168             return PAPI_ESYS;
01169      }
01170 
01171      did_something++;
01172       }
01173    }
01174 
01175    if (!did_something) {
01176       PAPIERROR("Did not enable any counters");
01177       return PAPI_EBUG;
01178    }
01179 
01180    pe_ctx->state |= PERF_EVENTS_RUNNING;
01181 
01182    return PAPI_OK;
01183 
01184 }

Here is the call graph for this function:

int _pe_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 1188 of file perf_event.c.

01189 {
01190     SUBDBG( "ENTER: ctx: %p, ctl: %p\n", ctx, ctl);
01191 
01192    int ret;
01193    int i;
01194    pe_context_t *pe_ctx = ( pe_context_t *) ctx;
01195    pe_control_t *pe_ctl = ( pe_control_t *) ctl;
01196 
01197    /* Just disable the group leaders */
01198    for ( i = 0; i < pe_ctl->num_events; i++ ) {
01199       if ( pe_ctl->events[i].group_leader_fd == -1 ) {
01200      ret=ioctl( pe_ctl->events[i].event_fd, PERF_EVENT_IOC_DISABLE, NULL);
01201      if ( ret == -1 ) {
01202         PAPIERROR( "ioctl(%d, PERF_EVENT_IOC_DISABLE, NULL) "
01203                "returned error, Linux says: %s",
01204                pe_ctl->events[i].event_fd, strerror( errno ) );
01205         return PAPI_EBUG;
01206      }
01207       }
01208    }
01209 
01210    pe_ctx->state &= ~PERF_EVENTS_RUNNING;
01211 
01212     SUBDBG( "EXIT:\n");
01213    return PAPI_OK;
01214 }

Here is the call graph for this function:

int _pe_stop_profiling ( ThreadInfo_t thread,
EventSetInfo_t ESI 
)

Definition at line 2096 of file perf_event.c.

02097 {
02098   int i, ret = PAPI_OK;
02099   pe_control_t *ctl;
02100   int cidx;
02101 
02102   ctl=ESI->ctl_state;
02103 
02104   cidx=ctl->cidx;
02105 
02106   /* Loop through all of the events and process those which have mmap */
02107   /* buffers attached.                                                */
02108   for ( i = 0; i < ctl->num_events; i++ ) {
02109     /* Use the mmap_buf field as an indicator of this fd being used for */
02110     /* profiling.                                                       */
02111     if ( ctl->events[i].mmap_buf ) {
02112       /* Process any remaining samples in the sample buffer */
02113       ret = process_smpl_buf( i, &thread, cidx );
02114       if ( ret ) {
02115     PAPIERROR( "process_smpl_buf returned error %d", ret );
02116     return ret;
02117       }
02118     }
02119   }
02120   return ret;
02121 }

Here is the call graph for this function:

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

Definition at line 1221 of file perf_event.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 912 of file perf_event.c.

00914 {
00915    ( void ) ctx;             /*unused */
00916    ( void ) ctl;             /*unused */
00917    ( void ) from;            /*unused */
00918    /*
00919     * Counters cannot be written.  Do we need to virtualize the
00920     * counters so that they can be written, or perhaps modify code so that
00921     * they can be written? FIXME ?
00922     */
00923 
00924     return PAPI_ENOSUPP;
00925 }

static int bug_check_scheduability ( void   )  [static]

Definition at line 185 of file perf_event.c.

00185                               {
00186 
00187 #if defined(__powerpc__)
00188   /* PowerPC not affected by this bug */
00189 #elif defined(__mips__)
00190   /* MIPS as of kernel 3.1 does not properly detect schedulability */
00191   return 1;
00192 #else
00193   if (_papi_os_info.os_version < LINUX_VERSION(2,6,33)) return 1;
00194 #endif
00195 
00196   if (nmi_watchdog_active) return 1;
00197 
00198   return 0;
00199 }

Here is the caller graph for this function:

static int bug_format_group ( void   )  [static]

Definition at line 207 of file perf_event.c.

00207                        {
00208 
00209   if (_papi_os_info.os_version < LINUX_VERSION(2,6,34)) return 1;
00210 
00211   /* MIPS, as of version 3.1, does not support this properly */
00212 
00213 #if defined(__mips__)
00214   return 1;
00215 #endif
00216 
00217   return 0;
00218 
00219 }

Here is the caller graph for this function:

static int bug_sync_read ( void   )  [static]

Definition at line 227 of file perf_event.c.

00227                     {
00228 
00229   if (_papi_os_info.os_version < LINUX_VERSION(2,6,33)) return 1;
00230 
00231   return 0;
00232 
00233 }

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

00431 {
00432    int ev_fd;
00433    struct perf_event_attr attr;
00434 
00435    long pid;
00436 
00437    /* clearing this will set a type of hardware and to count all domains */
00438    memset(&attr, '\0', sizeof(attr));
00439    attr.read_format = get_read_format(multiplex, inherit, 1);
00440 
00441    /* set the event id (config field) to instructios */
00442    /* (an event that should always exist)            */
00443    /* This was cycles but that is missing on Niagara */
00444    attr.config = PERF_COUNT_HW_INSTRUCTIONS;
00445 
00446    /* now set up domains this event set will be counting */
00447    if (!(domain & PAPI_DOM_SUPERVISOR)) {
00448       attr.exclude_hv = 1;
00449    }
00450    if (!(domain & PAPI_DOM_USER)) {
00451       attr.exclude_user = 1;
00452    }
00453    if (!(domain & PAPI_DOM_KERNEL)) {
00454       attr.exclude_kernel = 1;
00455    }
00456 
00457    if (granularity==PAPI_GRN_SYS) {
00458       pid = -1;
00459    } else {
00460       pid = tid;
00461    }
00462 
00463    SUBDBG("Calling sys_perf_event_open() from check_permissions\n");
00464 
00465    ev_fd = sys_perf_event_open( &attr, pid, cpu_num, -1, 0 );
00466    if ( ev_fd == -1 ) {
00467       SUBDBG("sys_perf_event_open returned error.  Linux says, %s", 
00468          strerror( errno ) );
00469       return map_perf_event_errors_to_papi(errno);
00470    }
00471 
00472    /* now close it, this was just to make sure we have permissions */
00473    /* to set these options                                         */
00474    close(ev_fd);
00475    return PAPI_OK;
00476 }

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

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

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

00766 {
00767    int i;
00768    int num_closed=0;
00769    int events_not_opened=0;
00770 
00771    /* should this be a more serious error? */
00772    if ( ctx->state & PERF_EVENTS_RUNNING ) {
00773       SUBDBG("Closing without stopping first\n");
00774    }
00775 
00776    /* Close child events first */
00777    for( i=0; i<ctl->num_events; i++ ) {
00778 
00779       if (ctl->events[i].event_opened) {
00780 
00781          if (ctl->events[i].group_leader_fd!=-1) {
00782             if ( ctl->events[i].mmap_buf ) {
00783            if ( munmap ( ctl->events[i].mmap_buf,
00784                      ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
00785               PAPIERROR( "munmap of fd = %d returned error: %s",
00786                  ctl->events[i].event_fd, strerror( errno ) );
00787               return PAPI_ESYS;
00788            }
00789         }
00790 
00791             if ( close( ctl->events[i].event_fd ) ) {
00792            PAPIERROR( "close of fd = %d returned error: %s",
00793                ctl->events[i].event_fd, strerror( errno ) );
00794            return PAPI_ESYS;
00795         } else {
00796            num_closed++;
00797         }
00798         ctl->events[i].event_opened=0;
00799      }
00800       }
00801       else {
00802     events_not_opened++;
00803       }
00804    }
00805 
00806    /* Close the group leaders last */
00807    for( i=0; i<ctl->num_events; i++ ) {
00808 
00809       if (ctl->events[i].event_opened) {
00810 
00811          if (ctl->events[i].group_leader_fd==-1) {
00812             if ( ctl->events[i].mmap_buf ) {
00813            if ( munmap ( ctl->events[i].mmap_buf,
00814                      ctl->events[i].nr_mmap_pages * getpagesize() ) ) {
00815               PAPIERROR( "munmap of fd = %d returned error: %s",
00816                  ctl->events[i].event_fd, strerror( errno ) );
00817               return PAPI_ESYS;
00818            }
00819         }
00820 
00821 
00822             if ( close( ctl->events[i].event_fd ) ) {
00823            PAPIERROR( "close of fd = %d returned error: %s",
00824                ctl->events[i].event_fd, strerror( errno ) );
00825            return PAPI_ESYS;
00826         } else {
00827            num_closed++;
00828         }
00829         ctl->events[i].event_opened=0;
00830      }
00831       }
00832    }
00833 
00834 
00835    if (ctl->num_events!=num_closed) {
00836       if (ctl->num_events!=(num_closed+events_not_opened)) {
00837          PAPIERROR("Didn't close all events: "
00838            "Closed %d Not Opened: %d Expected %d",
00839            num_closed,events_not_opened,ctl->num_events);
00840          return PAPI_EBUG;
00841       }
00842    }
00843 
00844    ctl->num_events=0;
00845 
00846    ctx->state &= ~PERF_EVENTS_OPENED;
00847 
00848    return PAPI_OK;
00849 }

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

00241                         {
00242 
00243    int ret;
00244    struct f_owner_ex fown_ex;
00245 
00246       /* F_SETOWN_EX is not available until 2.6.32 */
00247    if (_papi_os_info.os_version < LINUX_VERSION(2,6,32)) {
00248 
00249       /* get ownership of the descriptor */
00250       ret = fcntl( fd, F_SETOWN, mygettid(  ) );
00251       if ( ret == -1 ) {
00252      PAPIERROR( "cannot fcntl(F_SETOWN) on %d: %s", fd, strerror(errno) );
00253      return PAPI_ESYS;
00254       }
00255    }
00256    else {
00257       /* set ownership of the descriptor */
00258       fown_ex.type = F_OWNER_TID;
00259       fown_ex.pid  = mygettid();
00260       ret = fcntl(fd, F_SETOWN_EX, (unsigned long)&fown_ex );
00261 
00262       if ( ret == -1 ) {
00263      PAPIERROR( "cannot fcntl(F_SETOWN_EX) on %d: %s",
00264             fd, strerror( errno ) );
00265      return PAPI_ESYS;
00266       }
00267    }
00268    return PAPI_OK;
00269 }

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

01898 {
01899   int pos, esi_index, count;
01900 
01901   for ( count = 0; count < ESI->profile.event_counter; count++ ) {
01902     esi_index = ESI->profile.EventIndex[count];
01903     pos = ESI->EventInfoArray[esi_index].pos[0];
01904                 
01905     if ( pos == evt_idx ) {
01906       *profile_index = count;
01907           *native_index = ESI->NativeInfoArray[pos].ni_event & 
01908         PAPI_NATIVE_AND_MASK;
01909           *flags = ESI->profile.flags;
01910           SUBDBG( "Native event %d is at profile index %d, flags %d\n",
01911                   *native_index, *profile_index, *flags );
01912           return PAPI_OK;
01913     }
01914   }
01915   PAPIERROR( "wrong count: %d vs. ESI->profile.event_counter %d", count,
01916          ESI->profile.event_counter );
01917   return PAPI_EBUG;
01918 }

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

00278 {
00279    unsigned int format = 0;
00280 
00281    /* if we need read format options for multiplexing, add them now */
00282    if (multiplex) {
00283       format |= PERF_FORMAT_TOTAL_TIME_ENABLED;
00284       format |= PERF_FORMAT_TOTAL_TIME_RUNNING;
00285    }
00286 
00287    /* if our kernel supports it and we are not using inherit, */
00288    /* add the group read options                              */
00289    if ( (!bug_format_group()) && !inherit) {
00290       if (format_group) {
00291      format |= PERF_FORMAT_GROUP;
00292       }
00293    }
00294 
00295    SUBDBG("multiplex: %d, inherit: %d, group_leader: %d, format: %#x\n",
00296       multiplex, inherit, format_group, format);
00297 
00298    return format;
00299 }

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

00376                                                                {
00377 
00378    int ret;
00379 
00380    /* These mappings are approximate.
00381       EINVAL in particular can mean lots of different things */
00382    switch(perf_event_error) {
00383       case EPERM:
00384       case EACCES:
00385            ret = PAPI_EPERM;
00386        break;
00387       case ENODEV:
00388       case EOPNOTSUPP:
00389        ret = PAPI_ENOSUPP;
00390            break;
00391       case ENOENT:
00392        ret = PAPI_ENOEVNT;
00393            break;
00394       case ENOSYS:
00395       case EAGAIN:
00396       case EBUSY:
00397       case E2BIG:   /* Only happens if attr is the wrong size somehow */
00398       case EBADF:   /* We are attempting to group with an invalid file descriptor */
00399        ret = PAPI_ESYS;
00400        break;
00401       case ENOMEM:
00402        ret = PAPI_ENOMEM;
00403        break;
00404       case EMFILE:  /* Out of file descriptors.  Typically max out at 1024 */
00405            ret = PAPI_ECOUNT;
00406            break;
00407       case EINVAL:
00408       default:
00409        ret = PAPI_EINVAL;
00410            break;
00411    }
00412    return ret;
00413 }

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

01827 {
01828   uint64_t head = mmap_read_head( pe );
01829   uint64_t old = pe->tail;
01830   unsigned char *data = ((unsigned char*)pe->mmap_buf) + getpagesize(  );
01831   int diff;
01832 
01833   diff = head - old;
01834   if ( diff < 0 ) {
01835     SUBDBG( "WARNING: failed to keep up with mmap data. head = %" PRIu64
01836         ",  tail = %" PRIu64 ". Discarding samples.\n", head, old );
01837     /* head points to a known good entry, start there. */
01838     old = head;
01839   }
01840 
01841   for( ; old != head; ) {
01842     perf_sample_event_t *event = ( perf_sample_event_t * ) 
01843       & data[old & pe->mask];
01844     perf_sample_event_t event_copy;
01845     size_t size = event->header.size;
01846 
01847     /* Event straddles the mmap boundary -- header should always */
01848     /* be inside due to u64 alignment of output.                 */
01849     if ( ( old & pe->mask ) + size != ( ( old + size ) & pe->mask ) ) {
01850       uint64_t offset = old;
01851       uint64_t len = min( sizeof ( *event ), size ), cpy;
01852       void *dst = &event_copy;
01853 
01854       do {
01855     cpy = min( pe->mask + 1 - ( offset & pe->mask ), len );
01856     memcpy( dst, &data[offset & pe->mask], cpy );
01857     offset += cpy;
01858     dst = ((unsigned char*)dst) + cpy;
01859     len -= cpy;
01860       } while ( len );
01861 
01862       event = &event_copy;
01863     }
01864     old += size;
01865 
01866     SUBDBG( "event->type = %08x\n", event->header.type );
01867     SUBDBG( "event->size = %d\n", event->header.size );
01868 
01869     switch ( event->header.type ) {
01870     case PERF_RECORD_SAMPLE:
01871       _papi_hwi_dispatch_profile( ( *thr )->running_eventset[cidx],
01872                   ( caddr_t ) ( unsigned long ) event->ip.ip, 
01873                   0, profile_index );
01874       break;
01875 
01876     case PERF_RECORD_LOST:
01877       SUBDBG( "Warning: because of a mmap buffer overrun, %" PRId64
01878                       " events were lost.\n"
01879                       "Loss was recorded when counter id %#"PRIx64 
01880           " overflowed.\n", event->lost.lost, event->lost.id );
01881       break;
01882 
01883     default:
01884       SUBDBG( "Error: unexpected header type - %d\n",
01885           event->header.type );
01886       break;
01887     }
01888   }
01889 
01890   pe->tail = old;
01891   mmap_write_tail( pe, old );
01892 }

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

01781 {
01782   struct perf_event_mmap_page *pc = pe->mmap_buf;
01783   int head;
01784 
01785   if ( pc == NULL ) {
01786     PAPIERROR( "perf_event_mmap_page is NULL" );
01787     return 0;
01788   }
01789 
01790   head = pc->data_head;
01791   rmb(  );
01792 
01793   return head;
01794 }

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

01798 {
01799   struct perf_event_mmap_page *pc = pe->mmap_buf;
01800 
01801   /* ensure all reads are done before we write the tail out. */
01802   pc->data_tail = tail;
01803 }

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

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

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

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

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

01925 {
01926   int ret, flags, profile_index;
01927   unsigned native_index;
01928   pe_control_t *ctl;
01929 
01930   ret = find_profile_index( ( *thr )->running_eventset[cidx], evt_idx, 
01931                 &flags, &native_index, &profile_index );
01932   if ( ret != PAPI_OK ) {
01933     return ret;
01934   }
01935 
01936   ctl= (*thr)->running_eventset[cidx]->ctl_state;
01937 
01938   mmap_read( cidx, thr, 
01939          &(ctl->events[evt_idx]),
01940          profile_index );
01941 
01942   return PAPI_OK;
01943 }

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

00103                                             {
00104 
00105    /* Error out if kernel too early to support p4 */
00106    if (( vendor == PAPI_VENDOR_INTEL ) && (family == 15)) {
00107       if (_papi_os_info.os_version < LINUX_VERSION(2,6,35)) {
00108          PAPIERROR("Pentium 4 not supported on kernels before 2.6.35");
00109          return PAPI_ENOSUPP;
00110       }
00111    }
00112    return PAPI_OK;
00113 }

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

00327 {
00328     int ret;
00329 
00330    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);
00331    SUBDBG("   type: %d\n",hw_event->type);
00332    SUBDBG("   size: %d\n",hw_event->size);
00333    SUBDBG("   config: %"PRIx64" (%"PRIu64")\n",hw_event->config, hw_event->config);
00334    SUBDBG("   sample_period: %"PRIu64"\n",hw_event->sample_period);
00335    SUBDBG("   sample_type: %"PRIu64"\n",hw_event->sample_type);
00336    SUBDBG("   read_format: %"PRIu64"\n",hw_event->read_format);
00337    SUBDBG("   disabled: %d\n",hw_event->disabled);
00338    SUBDBG("   inherit: %d\n",hw_event->inherit);
00339    SUBDBG("   pinned: %d\n",hw_event->pinned);
00340    SUBDBG("   exclusive: %d\n",hw_event->exclusive);
00341    SUBDBG("   exclude_user: %d\n",hw_event->exclude_user);
00342    SUBDBG("   exclude_kernel: %d\n",hw_event->exclude_kernel);
00343    SUBDBG("   exclude_hv: %d\n",hw_event->exclude_hv);
00344    SUBDBG("   exclude_idle: %d\n",hw_event->exclude_idle);
00345    SUBDBG("   mmap: %d\n",hw_event->mmap);
00346    SUBDBG("   comm: %d\n",hw_event->comm);
00347    SUBDBG("   freq: %d\n",hw_event->freq);
00348    SUBDBG("   inherit_stat: %d\n",hw_event->inherit_stat);
00349    SUBDBG("   enable_on_exec: %d\n",hw_event->enable_on_exec);
00350    SUBDBG("   task: %d\n",hw_event->task);
00351    SUBDBG("   watermark: %d\n",hw_event->watermark);
00352    SUBDBG("   precise_ip: %d\n",hw_event->precise_ip);
00353    SUBDBG("   mmap_data: %d\n",hw_event->mmap_data);
00354    SUBDBG("   sample_id_all: %d\n",hw_event->sample_id_all);
00355    SUBDBG("   exclude_host: %d\n",hw_event->exclude_host);
00356    SUBDBG("   exclude_guest: %d\n",hw_event->exclude_guest);
00357    SUBDBG("   exclude_callchain_kernel: %d\n",hw_event->exclude_callchain_kernel);
00358    SUBDBG("   exclude_callchain_user: %d\n",hw_event->exclude_callchain_user);
00359    SUBDBG("   wakeup_events: %"PRIx32" (%"PRIu32")\n", hw_event->wakeup_events, hw_event->wakeup_events);
00360    SUBDBG("   bp_type: %"PRIx32" (%"PRIu32")\n", hw_event->bp_type, hw_event->bp_type);
00361    SUBDBG("   config1: %"PRIx64" (%"PRIu64")\n", hw_event->config1, hw_event->config1);
00362    SUBDBG("   config2: %"PRIx64" (%"PRIu64")\n", hw_event->config2, hw_event->config2);
00363    SUBDBG("   branch_sample_type: %"PRIx64" (%"PRIu64")\n", hw_event->branch_sample_type, hw_event->branch_sample_type);
00364    SUBDBG("   sample_regs_user: %"PRIx64" (%"PRIu64")\n", hw_event->sample_regs_user, hw_event->sample_regs_user);
00365    SUBDBG("   sample_stack_user: %"PRIx32" (%"PRIu32")\n", hw_event->sample_stack_user, hw_event->sample_stack_user);
00366 
00367     ret =
00368         syscall( __NR_perf_event_open, hw_event, pid, cpu, group_fd, flags );
00369     SUBDBG("Returned %d %d %s\n",ret,
00370            ret<0?errno:0,
00371            ret<0?strerror(errno):" ");
00372     return ret;
00373 }

Here is the caller graph for this function:

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

Definition at line 572 of file perf_event.c.

00573 {
00574    int ret;
00575    void *buf_addr;
00576    int fd = ctl->events[evt_idx].event_fd;
00577 
00578    /* Register that we would like a SIGIO notification when a mmap'd page */
00579    /* becomes full.                                                       */
00580    ret = fcntl( fd, F_SETFL, O_ASYNC | O_NONBLOCK );
00581    if ( ret ) {
00582       PAPIERROR ( "fcntl(%d, F_SETFL, O_ASYNC | O_NONBLOCK) "
00583           "returned error: %s", fd, strerror( errno ) );
00584       return PAPI_ESYS;
00585    }
00586 
00587    /* Set the F_SETOWN_EX flag on the fd.                          */
00588    /* This affects which thread an overflow signal gets sent to.   */
00589    ret=fcntl_setown_fd(fd);
00590    if (ret!=PAPI_OK) return ret;
00591 
00592    /* Set FD_CLOEXEC.  Otherwise if we do an exec with an overflow */
00593    /* running, the overflow handler will continue into the exec()'d*/
00594    /* process and kill it because no signal handler is set up.     */
00595    ret=fcntl(fd, F_SETFD, FD_CLOEXEC);
00596    if (ret) {
00597       return PAPI_ESYS;
00598    }
00599 
00600    /* when you explicitely declare that you want a particular signal,  */
00601    /* even with you use the default signal, the kernel will send more  */
00602    /* information concerning the event to the signal handler.          */
00603    /*                                                                  */
00604    /* In particular, it will send the file descriptor from which the   */
00605    /* event is originating which can be quite useful when monitoring   */
00606    /* multiple tasks from a single thread.                             */
00607    ret = fcntl( fd, F_SETSIG, ctl->overflow_signal );
00608    if ( ret == -1 ) {
00609       PAPIERROR( "cannot fcntl(F_SETSIG,%d) on %d: %s",
00610          ctl->overflow_signal, fd,
00611          strerror( errno ) );
00612       return PAPI_ESYS;
00613    }
00614 
00615    /* mmap() the sample buffer */
00616    buf_addr = mmap( NULL, ctl->events[evt_idx].nr_mmap_pages * getpagesize(),
00617             PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
00618    if ( buf_addr == MAP_FAILED ) {
00619       PAPIERROR( "mmap(NULL,%d,%d,%d,%d,0): %s",
00620          ctl->events[evt_idx].nr_mmap_pages * getpagesize(  ), 
00621          PROT_READ, MAP_SHARED, fd, strerror( errno ) );
00622       return ( PAPI_ESYS );
00623    }
00624 
00625    SUBDBG( "Sample buffer for fd %d is located at %p\n", fd, buf_addr );
00626 
00627    /* Set up the mmap buffer and its associated helpers */
00628    ctl->events[evt_idx].mmap_buf = (struct perf_counter_mmap_page *) buf_addr;
00629    ctl->events[evt_idx].tail = 0;
00630    ctl->events[evt_idx].mask = ( ctl->events[evt_idx].nr_mmap_pages - 1 ) *
00631                                getpagesize() - 1;
00632 
00633    return PAPI_OK;
00634 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 65 of file perf_event.c.

Definition at line 62 of file perf_event.c.

int our_cidx [static]

Definition at line 69 of file perf_event.c.

Definition at line 68 of file perf_event.c.


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1