void Performance::_add(perf_type_id type, long long config) { struct perf_event_attr pe; memset(&pe, 0, sizeof(struct perf_event_attr)); pe.size = sizeof(struct perf_event_attr); pe.exclude_kernel = 1; pe.exclude_hv = 1; pe.type = type; pe.config = config; order[events].type = type; order[events].config = config; events++; if (fd == -1) { /* if changed: change calculations in get */ pe.read_format = PERF_FORMAT_GROUP; pe.disabled = 1; fd = perf_event_open(&pe, 0, -1, -1, 0); if (fd < 0) { fprintf(stderr, "Error opening leader for %llx / %llx\n", (long long) type, config); exit(EXIT_FAILURE); } } else { int ret = perf_event_open(&pe, 0, -1, fd, 0); if (ret < 0) { fprintf(stderr, "Error connecting to leader for %llx / %llx\n", (long long) type, config); exit(EXIT_FAILURE); } } }
int *fd_group_init(int num_events, char **events) { struct perf_event_attr *attr; int fd, ret, leader_fd, i; int *fds = malloc(num_events * sizeof(int)); if (!fds) err(1, "could not allocate memory"); attr = calloc(num_events, sizeof(*attr)); // do refs, then misses for (i = 0; i < num_events; i++) { /* * 1st argument: event string * 2nd argument: default privilege level (used if not specified in the event string) * 3rd argument: the perf_event_attr to initialize */ ret = pfm_get_perf_event_encoding(events[i], PFM_PLM3, &attr[i], NULL, NULL); if (ret != PFM_SUCCESS) errx(1, "evt %d: cannot find encoding: %s", i, pfm_strerror(ret)); printf("Using encoding %lx for event %s\n", attr[i].config, events[i]); attr[i].inherit = 0; // inheritance currently doesn't work with FORMAT_GROUP /* * request timing information because event may be multiplexed * and thus it may not count all the time. The scaling information * will be used to scale the raw count as if the event had run all * along */ attr[i].read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_GROUP; /* do not start immediately after perf_event_open() */ attr[i].disabled = 1; /* * create the event and attach to self * Note that it attaches only to the main thread, there is no inheritance * to threads that may be created subsequently. * * if mulithreaded, then getpid() must be replaced by gettid() */ if (i == 0) { fd = perf_event_open(&attr[i], 0, -1, -1, 0); fds[i] = fd; leader_fd = fd; } else { fd = perf_event_open(&attr[i], 0, -1, leader_fd, 0); fds[i] = fd; } if (fd < 0) { warn("warning: evt %d: cannot create event", i); free(attr); free(fds); return NULL; } } free(attr); return fds; }
static void setup(void) { int i; struct perf_event_attr tsk_event, hw_event; /* * According to perf_event_open's manpage, the official way of * knowing if perf_event_open() support is enabled is checking for * the existence of the file /proc/sys/kernel/perf_event_paranoid. */ if (access("/proc/sys/kernel/perf_event_paranoid", F_OK) == -1) tst_brkm(TCONF, NULL, "Kernel doesn't have perf_event support"); tst_sig(NOFORK, DEF_HANDLER, cleanup); TEST_PAUSE; nhw = count_hardware_counters(); n = nhw + 4; memset(&hw_event, 0, sizeof(struct perf_event_attr)); memset(&tsk_event, 0, sizeof(struct perf_event_attr)); tsk_event.type = PERF_TYPE_SOFTWARE; tsk_event.size = sizeof(struct perf_event_attr); tsk_event.disabled = 1; tsk_event.config = PERF_COUNT_SW_TASK_CLOCK; hw_event.type = PERF_TYPE_HARDWARE; hw_event.size = sizeof(struct perf_event_attr); hw_event.disabled = 1; hw_event.config = PERF_COUNT_HW_INSTRUCTIONS; tsk0 = perf_event_open(&tsk_event, 0, -1, -1, 0); if (tsk0 == -1) { tst_brkm(TBROK | TERRNO, cleanup, "perf_event_open failed"); } else { tsk_event.disabled = 0; for (i = 0; i < n; ++i) { hwfd[i] = perf_event_open(&hw_event, 0, -1, -1, 0); tskfd[i] = perf_event_open(&tsk_event, 0, -1, hwfd[i], 0); if (tskfd[i] == -1 || hwfd[i] == -1) { tst_brkm(TBROK | TERRNO, cleanup, "perf_event_open failed"); } } } }
struct mmap_pages * perf_event__open(struct event_open *e_open) { int fd = -1; e_open->attr.disabled = 0; e_open->attr.size = sizeof(e_open->attr); e_open->attr.sample_period = 1; e_open->attr.inherit = 1; e_open->attr.sample_type = PERF_SAMPLE_TIME | PERF_SAMPLE_RAW | PERF_SAMPLE_CPU | PERF_SAMPLE_TID ; e_open->attr.__reserved_1 = 0; e_open->attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING ; fd = perf_event_open(&e_open->attr,e_open->pid,e_open->cpu \ ,e_open->group_id,e_open->flags); if(fd < 0) { fprintf(stderr,"Failed to open event FD\n"); return NULL; } struct mmap_pages *mmap_pages = NULL; mmap_pages = mmap_pages__new(fd,8); if(mmap_pages != NULL) { mmap_pages->attr = e_open->attr; fcntl(fd, F_SETFL, O_NONBLOCK); } return mmap_pages; }
int main(int ac, char **av) { int test = 0; int ret = 0; while (*++av) { if (!strcmp(*av, "--test")) { test = 1; continue; } struct perf_event_attr attr; if (resolve_event(*av, &attr) < 0) { fprintf(stderr, "Cannot resolve %s\n", *av); ret = 1; continue; } char *ev = format_raw_event(&attr, *av); printf("%s\n", ev); free(ev); if (test) { if (perf_event_open(&attr, 0, -1, -1, 0) < 0) perror("perf_event_open"); } } return ret; }
void perf_start(const char* kname) { if (!enabled) return; char* prof_envvar = getenv("MXPA_PROFILE"); int tids[32]; int ntid; get_tids(tids, &ntid); g_nthreads = ntid; int n; for (n = 0; n < ntid; n++) { int ret; ret = perf_setup_list_events(prof_envvar, &(g_fds[n]), &num_fds); perf_event_desc_t *fds = g_fds[n]; int cpu = -1; int group_fd = -1; int pid = tids[n]; fds[0].fd = -1; int i; for(i=0; i < num_fds; i++) { fds[i].hw.read_format = PERF_FORMAT_SCALE; fds[i].hw.disabled = 1; /* do not start now */ fds[i].hw.inherit = 1; /* XXX child process will inherit, when forked only? */ /* each event is in an independent group (multiplexing likely) */ fds[i].fd = perf_event_open(&fds[i].hw, pid, cpu, group_fd, 0); if (fds[i].fd == -1) { fprintf(stderr, "cannot open event %d\n", i); exit(2); } } } prctl(PR_TASK_PERF_EVENTS_ENABLE); }
void perfevent_initialize(char*events) { int i, ret; perfevent_events = strdup(events); /* * Initialize pfm library (required before we can use it) */ ret = pfm_initialize(); if (ret != PFM_SUCCESS) errx(1, "Cannot initialize library: %s", pfm_strerror(ret)); ret = perf_setup_list_events(events, &perfevent_fds, &perfevent_num_fds); if (ret || !perfevent_num_fds) errx(1, "cannot setup events"); perfevent_fds[0].fd = -1; for(i=0; i < perfevent_num_fds; i++) { /* request timing information necessary for scaling */ perfevent_fds[i].hw.read_format = PERF_FORMAT_SCALE; perfevent_fds[i].hw.disabled = (i == 0); /* do not start now */ perfevent_fds[i].hw.inherit = 1; /* pass on to child threads */ /* each event is in an independent group (multiplexing likely) */ perfevent_fds[i].fd = perf_event_open(&perfevent_fds[i].hw, 0, -1, perfevent_fds[0].fd, 0); if (perfevent_fds[i].fd == -1) err(1, "cannot open event %d", i); } }
void parent(int sock) { ssize_t size; int fd,i; struct perf_event_attr pe; memset(&pe,0,sizeof(struct perf_event_attr)); pe.type=PERF_TYPE_HARDWARE; pe.size=sizeof(struct perf_event_attr); pe.config=PERF_COUNT_HW_INSTRUCTIONS; pe.disabled=1; pe.exclude_kernel=1; pe.exclude_hv=1; arch_adjust_domain(&pe,quiet); fd=perf_event_open(&pe,0,-1,-1,0); if (fd<0) { fprintf(stderr,"Error opening leader %llx %s\n",pe.config,strerror(errno)); test_fail(test_string); } size = sock_fd_write(sock, "1", 1, fd); if (!quiet) printf ("wrote fd %d (size %d)\n", fd, (int)size); sleep(1); for(i=0;i<20;i++) instructions_million(); }
int setup_event(struct event *e, int cpu, struct event *leader, bool measure_all, int measure_pid) { e->attr.inherit = 1; if (!measure_all) { e->attr.disabled = 1; e->attr.enable_on_exec = 1; } e->attr.read_format |= PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; e->efd[cpu].fd = perf_event_open(&e->attr, measure_all ? -1 : measure_pid, cpu, leader ? leader->efd[cpu].fd : -1, 0); if (e->efd[cpu].fd < 0) { /* Handle offline CPU */ if (errno == EINVAL && !cpu_online(cpu)) return 0; fprintf(stderr, "Cannot open perf event for %s/%d: %s\n", e->event, cpu, strerror(errno)); return -1; } return 0; }
int main(int argc, char **argv) { int fd; struct perf_event_attr pe; int i; int result; long long counts[1],prev=0; long long total=0,average,max=0,min=0x7ffffffffffffffULL; memset(&pe,0,sizeof(struct perf_event_attr)); pe.type=PERF_TYPE_HARDWARE; pe.size=sizeof(struct perf_event_attr); pe.config=PERF_COUNT_HW_INSTRUCTIONS; pe.disabled=1; pe.exclude_kernel=1; pe.exclude_hv=1; fd=perf_event_open(&pe,0,-1,-1,0); if (fd<0) { fprintf(stderr,"Error opening leader %llx %s\n",pe.config,strerror(errno)); exit(1); } ioctl(fd, PERF_EVENT_IOC_RESET, 0); ioctl(fd, PERF_EVENT_IOC_ENABLE,0); for(i=0;i<NUM_RUNS;i++) { result=instructions_million(); result=read(fd,&counts,sizeof(long long)); results[i]=counts[0]-prev; prev=counts[0]; } ioctl(fd, PERF_EVENT_IOC_DISABLE,0); close(fd); for(i=0;i<NUM_RUNS;i++) { total+=results[i]; if (results[i]>max) max=results[i]; if (results[i]<min) min=results[i]; } average=total/NUM_RUNS; printf("Average=%lld max=%lld min=%lld\n",average,max,min); (void) result; return 0; }
int measure(pid_t pid) { perf_event_desc_t *fds = NULL; int i, ret, num_fds = 0; char fn[32]; if (pfm_initialize() != PFM_SUCCESS) errx(1, "libpfm initialization failed\n"); ret = perf_setup_list_events(options.events, &fds, &num_fds); if (ret || (num_fds == 0)) exit(1); fds[0].fd = -1; for(i=0; i < num_fds; i++) { fds[i].hw.disabled = 0; /* start immediately */ /* request timing information necessary for scaling counts */ fds[i].hw.read_format = PERF_FORMAT_SCALE; fds[i].hw.pinned = !i && options.pinned; fds[i].fd = perf_event_open(&fds[i].hw, pid, -1, (options.group? fds[0].fd : -1), 0); if (fds[i].fd == -1) errx(1, "cannot attach event %s", fds[i].name); } /* * no notification is generated by perf_counters * when the monitored thread exits. Thus we need * to poll /proc/ to detect it has disappeared, * otherwise we have to wait until the end of the * timeout */ sprintf(fn, "/proc/%d/status", pid); while(access(fn, F_OK) == 0 && options.delay) { sleep(1); options.delay--; if (options.print) print_counts(fds, num_fds, 1); } if (options.delay) warn("thread %d terminated before timeout", pid); if (!options.print) print_counts(fds, num_fds, 0); for(i=0; i < num_fds; i++) close(fds[i].fd); free(fds); /* free libpfm resources cleanly */ pfm_terminate(); return 0; }
int main() { #ifdef __NR_perf_event_open struct perf_event_attr pe; int fd; long long count; memset(&pe, 0, sizeof(struct perf_event_attr)); pe.type = PERF_TYPE_SOFTWARE; pe.size = sizeof(struct perf_event_attr); pe.config = PERF_COUNT_SW_CPU_CLOCK; pe.disabled = 0; pe.exclude_kernel = 1; pe.exclude_hv = 1; fd = perf_event_open(&pe, 0, -1, -1, 0); //staptest// perf_event_open (XXXX, 0, -1, -1, 0x0) = NNNN sleep(1); ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); read(fd, &count, sizeof(count)); // Limit testing. fd = perf_event_open((struct perf_event_attr*)-1, 0, -1, -1, 0); #ifdef __s390__ //staptest// perf_event_open (0x[7]?[f]+, 0, -1, -1, 0x0) = -NNNN #else //staptest// perf_event_open (0x[f]+, 0, -1, -1, 0x0) = -NNNN #endif fd = perf_event_open(&pe, -1, -1, -1, 0); //staptest// perf_event_open (XXXX, -1, -1, -1, 0x0) = -NNNN fd = perf_event_open(&pe, 0, -1, -1, -1); //staptest// perf_event_open (XXXX, 0, -1, -1, PERF_FLAG_[^ ]+|XXXX) = -NNNN close(fd); #endif return 0; }
int setupHandler(int sig) { // Perf event settings struct perf_event_attr pe; memset(&pe, 0, sizeof(struct perf_event_attr)); pe.type = PERF_TYPE_HW_CACHE; pe.size = sizeof(struct perf_event_attr); pe.config = (PERF_COUNT_HW_CACHE_L1D << 0) | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16); //pe.config = (PERF_COUNT_HW_CACHE_L1D << 0) | (PERF_COUNT_HW_CACHE_OP_WRITE << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16); pe.disabled = 1; pe.exclude_kernel = 1; pe.exclude_hv = 1; // pe.exclude_callchain_kernel = 1; // pe.exclude_idle = 1; pe.sample_period = 1000; // pe.sample_id_all = 1; pe.sample_type=sample_type; // pe.precise_ip = 0; // pe.read_format=read_format; // Record those information when trap happens //pe.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR; // Create the perf_event for this thread on all CPUs with no event group int perf_fd = perf_event_open(&pe, 0, -1, -1, 0); if(perf_fd == -1) { fprintf(stderr, "Failed to open perf event file: %s\n", strerror(errno)); abort(); } // Setting up 9 pages to pass information about a trap our_mmap=mmap(NULL, 9*4096, PROT_READ|PROT_WRITE, MAP_SHARED, perf_fd, 0); // Set the perf_event file to async mode if(fcntl(perf_fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) { fprintf(stderr, "Failed to set perf event file to ASYNC mode: %s\n", strerror(errno)); abort(); } // Tell the file to send a SIGUSR1 when an event occurs if(fcntl(perf_fd, F_SETSIG, sig) == -1) { fprintf(stderr, "Failed to set perf event file's async signal: %s\n", strerror(errno)); abort(); } // Deliver the signal to this thread if(fcntl(perf_fd, F_SETOWN, getpid()) == -1) { fprintf(stderr, "Failed to set the owner of the perf event file: %s\n", strerror(errno)); abort(); } return perf_fd; }
int perf_init(unsigned int num_ctrs, ...) { va_list args; int ctr, ret = 0; number = num_ctrs; attr = (struct perf_event_attr*)calloc(num_ctrs, sizeof(struct perf_event_attr)); fds = (int*) malloc(sizeof(int) * num_ctrs); if (attr == NULL || fds == NULL) { perror("Could not allocate space for counter data: "); ret = -1; goto error; } //Configure each counter, staring with 1 va_start(args, num_ctrs); for (ctr=0; ctr<num_ctrs; ctr++) { unsigned event, conf; conf = va_arg(args, unsigned int) & 0xFFFFFF; event = conf & 0xFFFF; attr[ctr].type = PERF_TYPE_RAW; attr[ctr].config = event; /* generic PMU event*/ attr[ctr].disabled = 0; attr[ctr].pinned = 1; attr[ctr].inherit = 1; fds[ctr] = perf_event_open(&attr[ctr], getpid(), -1, -1, 0); if ((conf & PERFMON_EVENTSEL_OS) == 0) attr[ctr].exclude_kernel = 1; if ((conf & PERFMON_EVENTSEL_USR) == 0) attr[ctr].exclude_user= 1; if (fds[ctr] < 0) { perror("Opening performance counter"); goto error; } } va_end(args); return ret; error: number = 0; if (attr) { free(attr); attr = NULL; } if (fds) { free(fds); fds = NULL; } return ret; }
static int perf_open(void) { struct perf_event_attr attr; memset(&attr, 0, sizeof (attr)); attr.type = i915_type_id(); if (attr.type == 0) return -ENOENT; attr.config = I915_PERF_ENERGY; attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED; return perf_event_open(&attr, -1, 0, -1, 0); }
static int perf_tracepoint_open(struct gpu_perf *gp, const char *sys, const char *name, int (*func)(struct gpu_perf *, const void *)) { struct perf_event_attr attr; struct gpu_perf_sample *sample; int n, *fd; memset(&attr, 0, sizeof (attr)); attr.type = PERF_TYPE_TRACEPOINT; attr.config = tracepoint_id(sys, name); if (attr.config == 0) return ENOENT; attr.sample_period = 1; attr.sample_type = (PERF_SAMPLE_TIME | PERF_SAMPLE_STREAM_ID | PERF_SAMPLE_TID | PERF_SAMPLE_RAW); attr.read_format = PERF_FORMAT_ID; attr.exclude_guest = 1; n = gp->nr_cpus * (gp->nr_events+1); fd = realloc(gp->fd, n*sizeof(int)); sample = realloc(gp->sample, n*sizeof(*gp->sample)); if (fd == NULL || sample == NULL) return ENOMEM; gp->fd = fd; gp->sample = sample; fd += gp->nr_events * gp->nr_cpus; sample += gp->nr_events * gp->nr_cpus; for (n = 0; n < gp->nr_cpus; n++) { uint64_t track[2]; fd[n] = perf_event_open(&attr, -1, n, -1, 0); if (fd[n] == -1) return errno; /* read back the event to establish id->tracepoint */ if (read(fd[n], track, sizeof(track)) < 0) return errno; sample[n].id = track[1]; sample[n].func = func; } gp->nr_events++; return 0; }
EXTERNAL void sysPerfEventCreate(int id, const char *eventName) { TRACE_PRINTF("%s: sysPerfEventCreate\n", Me); struct perf_event_attr *pe = (perf_event_attrs + id); int ret = pfm_get_perf_event_encoding(eventName, PFM_PLM3, pe, NULL, NULL); if (ret != PFM_SUCCESS) { errx(1, "error creating event %d '%s': %s\n", id, eventName, pfm_strerror(ret)); } pe->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; pe->disabled = 1; pe->inherit = 1; perf_event_fds[id] = perf_event_open(pe, 0, -1, -1, 0); if (perf_event_fds[id] == -1) { err(1, "error in perf_event_open for event %d '%s'", id, eventName); } }
static int perf_i915_open(int config, int group) { struct perf_event_attr attr; memset(&attr, 0, sizeof (attr)); attr.type = i915_type_id(); if (attr.type == 0) return -ENOENT; attr.config = config; attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED; if (group == -1) attr.read_format |= PERF_FORMAT_GROUP; return perf_event_open(&attr, -1, 0, group, 0); }
static int kprobe_attach_one(kprobe_t *kp, const char *func) { struct perf_event_attr attr = {}; int efd, i, id; id = kprobe_event_id(kp, func); if (id < 0) return id; attr.type = PERF_TYPE_TRACEPOINT; attr.sample_type = PERF_SAMPLE_RAW; attr.sample_period = 1; attr.wakeup_events = 1; attr.config = id; for (i = 0; i < /* sysconf(_SC_NPROCESSORS_ONLN) */ 1; i++) { efd = perf_event_open(&attr, -1/*pid*/, i/*cpu*/, -1/*group_fd*/, 0); if (efd < 0) { perror("perf_event_open"); return -errno; } if (ioctl(efd, PERF_EVENT_IOC_ENABLE, 0)) { perror("perf enable"); close(efd); return -errno; } if (!i && ioctl(efd, PERF_EVENT_IOC_SET_BPF, kp->bfd)) { _pe("perf-set-bpf: %s", func); close(efd); return -errno; } if (kp->efds.len == kp->efds.cap) { size_t sz = kp->efds.cap * sizeof(*kp->efds.fds); kp->efds.fds = realloc(kp->efds.fds, sz << 1); assert(kp->efds.fds); kp->efds.cap <<= 1; } kp->efds.fds[kp->efds.len++] = efd; } return 1; }
int setup_perf_event(int cpu_id, PerfmonEvent* event) { struct perf_event_attr attr; if (event == NULL) { return -EINVAL; } if (cpu_event_fds[cpu_id] == NULL) { return -EFAULT; } if (cpu_event_fds[cpu_id][event->umask] != -1) { return 0; } memset(&attr, 0, sizeof(struct perf_event_attr)); attr.type = PERF_TYPE_SOFTWARE; attr.size = sizeof(struct perf_event_attr); attr.config = configList[event->umask]; attr.exclude_kernel = 1; attr.exclude_hv = 1; attr.disabled = 1; attr.inherit = 1; if (event->numberOfOptions > 0) { for(int j = 0; j < event->numberOfOptions; j++) { switch (event->options[j].type) { case EVENT_OPTION_COUNT_KERNEL: attr.exclude_kernel = 0; break; default: break; } } } cpu_event_fds[cpu_id][event->umask] = perf_event_open(&attr, 0, cpu_id, -1, 0); if (cpu_event_fds[cpu_id][event->umask] < 0) { printf("Setup of event %llu failed\n", event->umask); return -EFAULT; } return 0; }
/** * perf_fd_open - Open a perf event with ring buffer for the current thread * @p: perf_fd to initialize * @attr: perf event attribute to use * @buf_size_shift: log2 of buffer size. * Return: -1 on error, otherwise 0. */ int perf_fd_open(struct perf_fd *p, struct perf_event_attr *attr, int buf_size_shift) { p->pfd = perf_event_open(attr, 0, -1, -1, 0); if (p->pfd < 0) return -1; struct perf_event_mmap_page *mpage; mpage = mmap(NULL, perf_mmap_size(buf_size_shift), PROT_READ|PROT_WRITE, MAP_SHARED, p->pfd, 0); if (mpage == (struct perf_event_mmap_page *)-1L) { close(p->pfd); return -1; } p->mpage = mpage; p->buf_size_shift = buf_size_shift; return 0; }
int main(int argc, char **argv) { /* 1 */ memset(&pe[5],0,sizeof(struct perf_event_attr)); pe[5].type=PERF_TYPE_TRACEPOINT; pe[5].size=64; /* The upper bits are ignored so this maps to */ /* event_id of 1 */ /* debugfs/events/ftrace/function/id 1 */ pe[5].config=0x7fffffff00000001ULL; pe[5].sample_period=0xffffffffff000000ULL; pe[5].sample_type=PERF_SAMPLE_IP|PERF_SAMPLE_TIME|PERF_SAMPLE_READ| PERF_SAMPLE_ID|PERF_SAMPLE_PERIOD; fd[5]=perf_event_open(&pe[5],0,0,-1,0 /*0*/ ); if (fd[5]<0) { printf("Error opening event: %s\n",strerror(errno)); printf("This means the bug won't trigger, kernel probably too old\n"); } /* below not needed if you run the test twice? */ /* 2 */ //#if 0 memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = our_handler; sa.sa_flags = SA_SIGINFO; if (sigaction( SIGRTMIN+2, &sa, NULL) < 0) { printf("Error setting up signal handler\n"); } fcntl(fd[5], F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); fcntl(fd[5], F_SETSIG, SIGRTMIN+2); fcntl(fd[5], F_SETOWN,getpid()); //#endif /* Replayed 2 syscalls */ return 0; }
void redfst_perf_init_worker(){ struct perf_event_attr events[REDFST_PERF_NUM_EVENTS]; int fd[REDFST_PERF_NUM_EVENTS]; int cpu = sched_getcpu(); int i; for(i=0;i<REDFST_PERF_NUM_EVENTS;++i) event_init(events+i, gRedfstPerfEventCode[i]); events[0].disabled = 1; fd[0] = -1; for(i=0;i<REDFST_PERF_NUM_EVENTS;++i){ if(0 > (fd[i] = perf_event_open(events+i, 0, cpu, fd[0], 0))){ while(i) close(fd[i]); return; } ioctl(fd[i], PERF_EVENT_IOC_RESET, 0); } ioctl(fd[0], PERF_EVENT_IOC_RESET, 0); ioctl(fd[0], PERF_EVENT_IOC_ENABLE, 0); gFd[cpu] = fd[0]; }
int rdpmc_open(unsigned counter, struct rdpmc_ctx *ctx) { struct perf_event_attr attr = { .type = counter > 10 ? PERF_TYPE_RAW : PERF_TYPE_HARDWARE, .size = PERF_ATTR_SIZE_VER0, .config = counter, .sample_type = PERF_SAMPLE_READ, .exclude_kernel = 1, }; return rdpmc_open_attr(&attr, ctx, NULL); } /** * rdpmc_open_attr - initialize a raw ring 3 readable performance counter * @attr: perf struct %perf_event_attr for the counter * @ctx: Pointer to struct %rdpmc_ctx that is initialized. * @leader_ctx: context of group leader or NULL * * This allows more flexible setup with a custom &perf_event_attr. * For simple uses rdpmc_open() should be used instead. * Must be called for each thread using the counter. * Must be closed with rdpmc_close() */ int rdpmc_open_attr(struct perf_event_attr *attr, struct rdpmc_ctx *ctx, struct rdpmc_ctx *leader_ctx) { ctx->fd = perf_event_open(attr, 0, -1, leader_ctx ? leader_ctx->fd : -1, 0); if (ctx->fd < 0) { perror("perf_event_open"); return -1; } ctx->buf = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ, MAP_SHARED, ctx->fd, 0); if (ctx->buf == MAP_FAILED) { close(ctx->fd); perror("mmap on perf fd"); return -1; } return 0; }
int main(int argc, char **argv) { struct perf_event_attr pe; int fd; int quiet=0; int kernel_size; quiet=test_quiet(); if (!quiet) { printf("This test checks what happens if attr struct is " "exactly what the kernel expects.\n"); } kernel_size=sizeof(struct perf_event_attr); memset(&pe,0,kernel_size); pe.size=kernel_size; pe.type=PERF_TYPE_HARDWARE; pe.config=PERF_COUNT_HW_INSTRUCTIONS; pe.disabled=1; pe.exclude_kernel=1; pe.exclude_hv=1; arch_adjust_domain(&pe,quiet); fd=perf_event_open(&pe,0,-1,-1,0); if (fd<0) { fprintf(stderr,"Error opening leader %llx %s\n", pe.config,strerror(errno)); test_fail(test_string); } close(fd); test_pass(test_string); return 0; }
int perf_setup_counter(struct perf_event_attr *attr, const pid_t pid, const int cpu, const int group_fd, const unsigned long flags, int *counter_fd) { int fd; if (attr == NULL || counter_fd == NULL) return PQOS_RETVAL_PARAM; fd = perf_event_open(attr, pid, cpu, group_fd, flags); if (fd < 0) { LOG_ERROR("Failed to open perf event!\n"); return PQOS_RETVAL_ERROR; } *counter_fd = fd; return PQOS_RETVAL_OK; }
int pfm_init_counters(const char** counters) { #ifdef VERBOSE fprintf(stderr, "Initing counters\n"); #endif /* Initialize pfm library */ int i,ret; ret = pfm_initialize(); if (ret != PFM_SUCCESS) { fprintf(stderr, "Cannot initialize libpfm: %s\n", pfm_strerror(ret)); return -1; } ret = perf_setup_argv_events(counters, &fds, &num_fds); if (ret || !num_fds) { fprintf(stderr, "Cannot setup events\n"); return -1; } fds[0].fd = -1; for (i=0; i < num_fds; i++) { /* request timing information necessary for scaling */ fds[i].hw.read_format = PERF_FORMAT_SCALE; fds[i].hw.disabled = 1; /* start paused */ fds[i].fd = perf_event_open(&fds[i].hw, 0, -1, -1, 0); if (fds[i].fd == -1) { fprintf(stderr, "Cannot open event %d\n", i); return -1; } } counter_values = (uint64_t*) malloc(num_fds * sizeof(uint64_t)); return 0; }
int main(int argc, char** argv) { int ret,quiet,i; struct perf_event_attr pe; struct sigaction sa; void *our_mmap; char test_string[]="Testing overflows on sibling..."; quiet=test_quiet(); if (!quiet) printf("This tests that overflows of siblings work.\n"); memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = our_handler; sa.sa_flags = SA_SIGINFO; if (sigaction( SIGIO, &sa, NULL) < 0) { fprintf(stderr,"Error setting up signal handler\n"); exit(1); } memset(&pe,0,sizeof(struct perf_event_attr)); pe.type=PERF_TYPE_HARDWARE; pe.size=sizeof(struct perf_event_attr); pe.config=PERF_COUNT_HW_CPU_CYCLES; pe.sample_period=0; pe.sample_type=0; pe.read_format=PERF_FORMAT_GROUP|PERF_FORMAT_ID; pe.disabled=1; pe.pinned=0; pe.exclude_kernel=1; pe.exclude_hv=1; pe.wakeup_events=1; arch_adjust_domain(&pe,quiet); fd1=perf_event_open(&pe,0,-1,-1,0); if (fd1<0) { fprintf(stderr,"Error opening leader %llx\n",pe.config); test_fail(test_string); } pe.type=PERF_TYPE_HARDWARE; pe.config=PERF_COUNT_HW_INSTRUCTIONS; pe.sample_period=100000; pe.sample_type=PERF_SAMPLE_IP; pe.read_format=0; pe.disabled=0; pe.pinned=0; pe.exclude_kernel=1; pe.exclude_hv=1; arch_adjust_domain(&pe,quiet); fd2=perf_event_open(&pe,0,-1,fd1,0); if (fd2<0) { fprintf(stderr,"Error opening %llx\n",pe.config); test_fail(test_string); } /* large enough that threshold not a problem */ our_mmap=mmap(NULL, (1+MMAP_PAGES)*getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0); fcntl(fd2, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC); fcntl(fd2, F_SETSIG, SIGIO); fcntl(fd2, F_SETOWN,getpid()); ioctl(fd1, PERF_EVENT_IOC_RESET, 0); ioctl(fd2, PERF_EVENT_IOC_RESET, 0); ret=ioctl(fd1, PERF_EVENT_IOC_ENABLE,0); if (ret<0) { if (!quiet) fprintf(stderr,"Error with PERF_EVENT_IOC_ENABLE of group leader: " "%d %s\n",errno,strerror(errno)); test_fail(test_string); } for(i=0;i<100;i++) { instructions_million(); } ret=ioctl(fd1, PERF_EVENT_IOC_DISABLE,0); if (!quiet) printf("Count: %d %p\n",count.total,our_mmap); if (count.total==0) { if (!quiet) printf("No overflow events generated.\n"); test_fail(test_string); } if (count.total!=1000) { if (!quiet) printf("Expected %d overflows, got %d.\n", count.total,100); test_fail(test_string); } close(fd1); close(fd2); test_pass(test_string); return 0; }
int main(int argc, char** argv) { int fd1,i; struct perf_event_attr pe1; int errors=0; int result; char test_string[]="Testing PERF_EVENT_IOC_SET_FILTER ioctl..."; quiet=test_quiet(); if (!quiet) { printf("Testing PERF_EVENT_IOC_SET_FILTER ioctl.\n"); } /****************************************************/ /* Check if /sys/kernel/debug/tracing/events exists */ /****************************************************/ // result=access("/sys/kernel/debug/tracing/events",F_OK); /* Actually this is pointless, as it gives EACCESS */ /* as a normal user even if the file exists */ /************************************/ /* Creating a tracepoint event */ /************************************/ if (!quiet) { printf("Creating a tracepoint event\n"); } memset(&pe1,0,sizeof(struct perf_event_attr)); pe1.type=PERF_TYPE_TRACEPOINT; pe1.size=sizeof(struct perf_event_attr); /* Find a trace event that will let us add a particular filter */ /* It should work with */ /* writeback:writeback_start*/ /* but we can't get the id of this directly without debugfs/tracefs */ /* mounted (the id numbers change depending on machine/kernel) */ /* Valid filter */ strcpy(filter,"nr_pages==2"); if (!quiet) { printf("Trying to find an event that will allow filter %s\n", filter); } /* Usually there are fewer than 1000 trace events? */ for(i=0;i<MAX_SEARCH;i++) { pe1.config=i; pe1.disabled=1; pe1.exclude_kernel=0; pe1.exclude_hv=0; arch_adjust_domain(&pe1,quiet); fd1=perf_event_open(&pe1,0,-1,-1,0); if (fd1<0) { if (!quiet) { // fprintf(stderr,"Failed on %d\n",i); } continue; } result=ioctl(fd1, PERF_EVENT_IOC_SET_FILTER, filter); if (result==0) { if (!quiet) printf("Found proper event %d\n",i); close(fd1); break; } else { } close(fd1); } if (i==MAX_SEARCH) { if (!quiet) { printf("Could not find any trace event to filter\n"); } test_skip(test_string); errors++; } pe1.config=i; pe1.disabled=1; pe1.exclude_kernel=0; pe1.exclude_hv=0; arch_adjust_domain(&pe1,quiet); /* Create group leader */ fd1=perf_event_open(&pe1,0,-1,-1,0); if (fd1<0) { if (!quiet) { fprintf(stderr,"Unexpected error %s\n",strerror(errno)); } test_fail(test_string); } for(i=0;i<MAX_FILTER;i++) { filter[i]=0xff; } /* Check a too big value */ if (!quiet) { printf("\t+ Checking a too-big event: "); } result=ioctl(fd1, PERF_EVENT_IOC_SET_FILTER, filter); if ((result==-1) && (errno==EINVAL)) { if (!quiet) printf("Failed as expected\n"); } else { if (!quiet) printf("Unexpected %d %s\n",result,strerror(errno)); errors++; } /* Check off-by-one value */ /* Size limited to pagesize */ if (!quiet) { printf("\t+ Checking off-by-one filter: "); } filter[4096]=0; result=ioctl(fd1, PERF_EVENT_IOC_SET_FILTER, filter); if ((result==-1) && (errno==EINVAL)) { if (!quiet) printf("Failed as expected\n"); } else { if (!quiet) printf("Unexpected %d %s\n",result,strerror(errno)); errors++; } /* Check a just-right value */ if (!quiet) { printf("\t+ Checking max size invalid filter: "); } filter[4095]=0; result=ioctl(fd1, PERF_EVENT_IOC_SET_FILTER, filter); if ((result==-1) && (errno==EINVAL)) { if (!quiet) printf("Failed as expected\n"); } else { if (!quiet) printf("Unexpected %d %s\n",result,strerror(errno)); errors++; } /* Check an empty value */ if (!quiet) { printf("\t+ Checking empty filter: "); } filter[0]=0; result=ioctl(fd1, PERF_EVENT_IOC_SET_FILTER, filter); if ((result==-1) && (errno==EINVAL)) { if (!quiet) printf("Failed as expected\n"); } else { if (!quiet) printf("Unexpected %d %s\n",result,strerror(errno)); errors++; } /* Clear a filter */ if (!quiet) { printf("\t+ Clear filter (write 0): "); } filter[0]='0'; filter[1]=0; result=ioctl(fd1, PERF_EVENT_IOC_SET_FILTER, filter); if ((result==-1) && (errno==EINVAL)) { if (!quiet) printf("Failed as expected\n"); } else { if (!quiet) printf("Unexpected %d %s\n",result,strerror(errno)); errors++; } /* tracefs usually under /sys/kernel/tracing */ /* start */ ioctl(fd1, PERF_EVENT_IOC_RESET, 0); ioctl(fd1, PERF_EVENT_IOC_ENABLE,0); /* million */ result=instructions_million(); /* stop */ ioctl(fd1, PERF_EVENT_IOC_DISABLE,0); close(fd1); if (errors) { test_fail(test_string); } test_pass(test_string); return 0; }
static void open_event(char *line) { struct perf_event_attr *pe; int fd,orig_fd,remapped_group_fd; pid_t pid; int cpu,group_fd,orig_size; long int flags; unsigned char zeros[4096]; /* urgh, necessary. Took forever to track this down */ /* data from the poll structure was leaking in if not */ /* entirely zero, and also getting E2BIG errors if we */ /* set the size to a "too big" value and there were */ /* non-zero values in that space. */ /* The max size of a struct is the pagesize, so make */ /* all events live in a sea of zeros to avoid problems*/ memset(&zeros,0,4096); pe=(struct perf_event_attr *)&zeros; /* I hate bitfields */ int disabled,inherit,pinned,exclusive; int exclude_user,exclude_kernel,exclude_hv,exclude_idle; int mmap,comm,freq,inherit_stat; int enable_on_exec,task,watermark,precise_ip; int mmap_data,sample_id_all,exclude_host,exclude_guest; int exclude_callchain_user,exclude_callchain_kernel; int mmap2,comm_exec; sscanf(line, "%*c %d %d %d %d %lx " "%x %x " "%llx %llx %llx %llx " "%d %d %d %d " "%d %d %d %d " "%d %d %d %d " "%d %d %d %d " "%d %d %d %d " "%d %d " "%llx %llx %lld " "%d %d %lld %d %d %d", &orig_fd,&pid,&cpu,&group_fd,&flags, &pe->type,&pe->size, &pe->config,&pe->sample_period,&pe->sample_type,&pe->read_format, &disabled,&inherit,&pinned,&exclusive, &exclude_user,&exclude_kernel,&exclude_hv,&exclude_idle, &mmap,&comm,&freq,&inherit_stat, &enable_on_exec,&task,&watermark,&precise_ip, &mmap_data,&sample_id_all,&exclude_host,&exclude_guest, &pe->wakeup_events,&pe->bp_type, &pe->config1,&pe->config2,&pe->branch_sample_type, &exclude_callchain_kernel,&exclude_callchain_user, &pe->sample_regs_user,&pe->sample_stack_user,&mmap2,&comm_exec); errno=0; /* use recorded value for pid not our actual pid */ if (pid==original_pid) { pid=getpid(); } /* re-populate bitfields */ /* can't sscanf into them */ pe->disabled=disabled; pe->inherit=inherit; pe->pinned=pinned; pe->exclusive=exclusive; pe->exclude_user=exclude_user; pe->exclude_kernel=exclude_kernel; pe->exclude_hv=exclude_hv; pe->exclude_idle=exclude_idle; pe->mmap=mmap; pe->comm=comm; pe->freq=freq; pe->inherit_stat=inherit_stat; pe->enable_on_exec=enable_on_exec; pe->task=task; pe->watermark=watermark; pe->precise_ip=precise_ip; pe->mmap_data=mmap_data; pe->sample_id_all=sample_id_all; pe->exclude_host=exclude_host; pe->exclude_guest=exclude_guest; pe->exclude_callchain_user=exclude_callchain_user; pe->exclude_callchain_kernel=exclude_callchain_kernel; pe->mmap2=mmap2; pe->comm_exec=comm_exec; /* kernel over-writes this sometimes :( */ orig_size=pe->size; if (group_fd==-1) { remapped_group_fd=-1; } else { remapped_group_fd=fd_remap[group_fd]; } fd=perf_event_open(pe,pid,cpu,remapped_group_fd,flags); if (fd<0) { fprintf(stderr,"Line %lld Error opening %s : %s\n", line_num,line,strerror(errno)); perf_pretty_print_event(stderr,orig_fd,original_pid, pe, pid, cpu, remapped_group_fd,flags); if (errno==E2BIG) { printf("Too big! Kernel returns %d we were %d\n", pe->size,orig_size); } #if 0 { int i; char *blah; blah=(char *)&pe; printf("BEFORE\n"); for(i=0;i<100;i++) { printf("%d:%2x ",i,blah[i]); } printf("AFTER\n"); } #endif error=1; return; } if (orig_fd>FD_REMAP_SIZE) { fprintf(stderr,"fd out of range\n"); error=1; return; } fd_remap[orig_fd]=fd; if (fd>FD_REMAP_SIZE) { fprintf(stderr,"overflow fd out of range\n"); error=1; return; } fd_overflows[fd]=0; fd_throttles[fd]=0; }