Skip to content

Commit

Permalink
simultaenous_overflow
Browse files Browse the repository at this point in the history
foolish bug where I wasn't enabling both counters.  Only
worked by luck.
  • Loading branch information
deater committed Sep 14, 2012
1 parent 0458d08 commit 037970a
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
14 September 2012
+ Add simultaneous overflows test
+ Add simultaneous_group_overflow test
+ Add simultaneous_overflow

21 August 2012
+ Add check_reset_mpx test
Expand Down
1 change: 1 addition & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ echo "* Checking basic perf_event functionality"
./validation/inherit_stat
./validation/enable_on_exec
./validation/simultaneous_group_overflow
./validation/simultaneous_overflow

echo
echo "* Checking bugs that PAPI has to work around"
Expand Down
27 changes: 23 additions & 4 deletions validation/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ all: \
inherit_stat \
non-existent \
offcore_response \
simultaneous_group_overflow \
rdpmc_support \
rdpmc_validation \
simple_overflow_leader \
simple_overflow_sibling
simple_overflow_sibling \
simultaneous_group_overflow \
simultaneous_overflow


###

Expand Down Expand Up @@ -191,6 +193,21 @@ simultaneous_group_overflow.o: simultaneous_group_overflow.c
$(CC) $(CFLAGS) -c simultaneous_group_overflow.c


###


simultaneous_overflow: simultaneous_overflow.o ../lib/test_utils.o \
../lib/perf_helpers.o \
../lib/matrix_multiply.o
$(CC) $(LFLAGS) -o simultaneous_overflow simultaneous_overflow.o \
../lib/test_utils.o \
../lib/perf_helpers.o \
../lib/matrix_multiply.o

simultaneous_overflow.o: simultaneous_overflow.c
$(CC) $(CFLAGS) -c simultaneous_overflow.c


###

simple_overflow_leader: simple_overflow_leader.o ../lib/test_utils.o \
Expand Down Expand Up @@ -231,9 +248,11 @@ clean:
inherit_stat \
non-existent \
offcore_response \
simultaneous_group_overflow \
rdpmc_support \
rdpmc_validation \
simple_overflow_leader \
simple_overflow_sibling
simple_overflow_sibling \
simultaneous_group_overflow \
simultaneous_overflow


301 changes: 301 additions & 0 deletions validation/simultaneous_overflow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
/* simultaneous_overflow.c */
/* by Vince Weaver [email protected] */

/* Test to see if we can sample on two events at once */

/* A user was having a PAPI issue related to this */

#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 "perf_event.h"
#include "test_utils.h"
#include "perf_helpers.h"
#include "matrix_multiply.h"

#define NUM_EVENTS 2

struct {
int fd;
int overflows;
int individual_overflow;
} events[NUM_EVENTS];

#define SNB_TEST 1

#ifdef SNB_TEST
struct {
char name[BUFSIZ];
int type;
int config;
int period;
} event_values[NUM_EVENTS] = {
{ "PAPI_TOT_CYC", PERF_TYPE_RAW, 0x53003c, 4000000},
{ "PAPI_L2_TCM", PERF_TYPE_RAW, 0x53022e, 400000},
};
#else
struct {
char name[BUFSIZ];
int type;
int config;
int period;
} event_values[NUM_EVENTS] = {
{ "perf::instructions", PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, 1000000},
{ "perf::instructions", PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, 2000000},
};
#endif


static void our_handler(int signum,siginfo_t *info, void *uc) {

int ret,i;
int fd = info->si_fd;

ret=ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);

for(i=0;i<NUM_EVENTS;i++) {
if (events[i].fd==fd) {
events[i].overflows++;
break;
}
}

if (i==NUM_EVENTS) printf("fd %d not found\n",fd);

//printf("fd: %d overflowed\n",fd);
ret=ioctl(fd, PERF_EVENT_IOC_REFRESH,1);

(void) ret;

}



int main(int argc, char** argv) {

int ret,quiet,i,matches=0;

struct perf_event_attr pe;

struct sigaction sa;
void *our_mmap;
char test_string[]="Testing multiple event overflow...";

for(i=0;i<NUM_EVENTS;i++) {
events[i].fd=-1;
events[i].overflows=0;
}

quiet=test_quiet();

/*********************************************************************/
if (!quiet) printf("This tests simultaneous overflow.\n");
/*********************************************************************/

/*****************************/
/* set up our signal handler */
/*****************************/

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);
}

/***********************/
/* get expected counts */
/***********************/

for(i=0;i<NUM_EVENTS;i++) {
memset(&pe,0,sizeof(struct perf_event_attr));

pe.type=event_values[i].type;
pe.size=sizeof(struct perf_event_attr);
pe.config=event_values[i].config;
pe.sample_period=event_values[i].period;
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=0;

events[i].fd=perf_event_open(&pe,0,-1,-1,0);
if (events[i].fd<0) {
fprintf(stderr,"Error opening leader %llx\n",pe.config);
exit(1);
}

/* on older kernels you need this even if you don't use it */
our_mmap=mmap(NULL, (1+1)*4096,
PROT_READ|PROT_WRITE, MAP_SHARED, events[i].fd, 0);

fcntl(events[i].fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
fcntl(events[i].fd, F_SETSIG, SIGIO);
fcntl(events[i].fd, F_SETOWN,getpid());

ioctl(events[i].fd, PERF_EVENT_IOC_RESET, 0);

if (!quiet) {
printf("Testing matrix matrix multiply\n");
printf("\tEvent %s with period %d\n",
event_values[i].name,
event_values[i].period);
}

ret=ioctl(events[i].fd, PERF_EVENT_IOC_ENABLE,0);

printf("\t");
naive_matrix_multiply(quiet);

ret=ioctl(events[i].fd, PERF_EVENT_IOC_DISABLE,0);

if (!quiet) {
printf("\tfd %d overflows: %d (%s/%d)\n",
events[i].fd,events[i].overflows,
event_values[i].name,
event_values[i].period);
}
if (events[i].overflows==0) {
if (!quiet) printf("No overflow events generated.\n");
test_fail(test_string);
}

close(events[i].fd);

events[i].individual_overflow=events[i].overflows;

events[i].overflows=0;
events[i].fd=-1;
}


/**********************************/
/* test overflow for both */
/**********************************/

if (!quiet) {
printf("Testing matrix matrix multiply\n");
for(i=0;i<NUM_EVENTS;i++) {
printf("\tEvent %s with period %d\n",
event_values[i].name,
event_values[i].period);
}
}

for(i=0;i<NUM_EVENTS;i++) {

memset(&pe,0,sizeof(struct perf_event_attr));

pe.type=event_values[i].type;
pe.size=sizeof(struct perf_event_attr);
pe.config=event_values[i].config;
pe.sample_period=event_values[i].period;
pe.sample_type=PERF_SAMPLE_ID;
pe.read_format=PERF_FORMAT_GROUP|PERF_FORMAT_ID;
pe.disabled=1;
pe.pinned=1;
pe.exclude_kernel=1;
pe.exclude_hv=1;
pe.wakeup_events=0;

events[i].fd=perf_event_open(&pe,0,-1,-1,0);
if (events[i].fd<0) {
fprintf(stderr,"Error opening %llx\n",pe.config);
test_fail(test_string);
}

/* on older kernels you need this even if you don't use it */
our_mmap=mmap(NULL, (1+1)*4096,
PROT_READ|PROT_WRITE, MAP_SHARED, events[i].fd, 0);

fcntl(events[i].fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
fcntl(events[i].fd, F_SETSIG, SIGIO);
fcntl(events[i].fd, F_SETOWN,getpid());

ioctl(events[i].fd, PERF_EVENT_IOC_RESET, 0);
}

for(i=0;i<NUM_EVENTS;i++) {
ret=ioctl(events[i].fd, 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);
}

printf("\t");
naive_matrix_multiply(quiet);

for(i=0;i<NUM_EVENTS;i++) {
ret=ioctl(events[i].fd, PERF_EVENT_IOC_DISABLE,0);
}

for(i=0;i<NUM_EVENTS;i++) {
if (!quiet) {
printf("\tfd %d overflows: %d (%s/%d)\n",
events[i].fd,events[i].overflows,
event_values[i].name,event_values[i].period);
}
}

for(i=0;i<NUM_EVENTS;i++) {
if (events[i].overflows==0) {
if (!quiet) printf("No overflow events generated.\n");
test_fail(test_string);
}
}

for(i=0;i<NUM_EVENTS;i++) {
close(events[i].fd);
}


/* test validity */
for(i=0;i<NUM_EVENTS;i++) {

if (!quiet) fprintf(stderr,"Event %s/%d Expected %d Got %d\n",
event_values[i].name, event_values[i].period,
events[i].individual_overflow,events[i].overflows);


if (events[i].individual_overflow!=events[i].overflows) {
}
else{
matches++;
}
}

if (matches!=NUM_EVENTS) {
fprintf(stderr,"Wrong number of overflows!\n");
test_fail(test_string);
}


test_pass(test_string);

return 0;
}

0 comments on commit 037970a

Please sign in to comment.