lkml.org 
[lkml]   [2011]   [May]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: perf: regression with PERF_EVENT_IOC_REFRESH
On Mon, 23 May 2011, Peter Zijlstra wrote:

> > before the changeset, you could have a counter group where only one of the
> > subevents was sampling. PERF_EVENT_IOC_REFRESH would correctly enable
> > sampling for only that subevent.
>
> But how? it adds to the event_limit of the event you call the ioctl()
> on, not on any of the group siblings.

the old behavior did.

> > With the changeset applied, this fails with EINVALID. Now you can only
> > sample in a group leader.
>
> I'm not quite seeing how group-leaders are relevant here, you can only
> call this ioctl() on sampling events, regardless of if they're they
> group leader or a sibling.

previous behavior was that if you called it on a group leader that wasn't
sampling, a sibling event that was sampling would be activated.

> > Was this an intended change? It breaks various of our PAPI regression
> > tests that worked fine before the change was committed.
>
> I'm not quite seeing what's wrong yet, the change seemed simple enough
> in that calling that ioctl() on an event that wasn't capable of
> generating samples doesn't make sense, since it will increase the event
> limit for the event you call it on.

attached is some code that will return a sampled count on older kernels
but gives EINVAL on current kernels.

The old behavior might have been unintentional, but PAPI unfortunately
depends on it (not code I originaly wrote, but code I have to maintain).

Vince/* sampled_notleader_refresh.c */
/* by Vince Weaver vweaver1 _at_ eecs.utk.edu */
/* Compile with gcc -O2 -Wall -o sampled_notleader_refresh sampled_notleader_refresh.c */
#define _GNU_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/unistd.h>
#include <sys/prctl.h>
#include <linux/perf_event.h>


static int count=0;
static void our_handler(int signum,siginfo_t *oh, void *blah) {
count++;
}
int perf_event_open(struct perf_event_attr *hw_event_uptr,
pid_t pid, int cpu, int group_fd, unsigned long flags) {
return syscall(__NR_perf_event_open, hw_event_uptr, pid, cpu, group_fd,flags);
}
double busywork(int count) {
int i;
double sum=0.0012;
for(i=0;i<count;i++) {
sum+=0.01;
}
return sum;
}

int main(int argc, char** argv) {
int ret,fd1,fd2;
double result;
struct perf_event_attr pe;
struct sigaction sa;
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_INSTRUCTIONS;
pe.sample_period=000000;
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;
fd1=perf_event_open(&pe,0,-1,-1,0);
if (fd1<0) {
fprintf(stderr,"Error opening leader %llx\n",pe.config);
exit(1);
}
pe.type=PERF_TYPE_HARDWARE;
pe.config=PERF_COUNT_HW_INSTRUCTIONS;
pe.sample_period=1000000;
pe.sample_type=PERF_SAMPLE_IP;
pe.read_format=PERF_FORMAT_GROUP|PERF_FORMAT_ID;
pe.disabled=0;
pe.pinned=0;
pe.exclude_kernel=1;
pe.exclude_hv=1;
pe.wakeup_events=1;
fd2=perf_event_open(&pe,0,-1,fd1,0);
if (fd2<0) {
fprintf(stderr,"Error opening %llx\n",pe.config);
exit(1);
}

void *blargh;
/* important! */
blargh=mmap(NULL, (1+1)*4096,
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_REFRESH,0);
if (ret<0) {
fprintf(stderr,"Error with PERF_EVENT_IOC_REFRESH of group leader: "
"%d %s\n",errno,strerror(errno));
exit(1);
}
result=busywork(10000000);
ret=ioctl(fd2, PERF_EVENT_IOC_DISABLE,0);

printf("Count: %d %lf\n",count,result);

return 0;
}
\
 
 \ /
  Last update: 2011-05-24 08:23    [from the cache]
©2003-2011 Jasper Spaans