Skip to content

Commit

Permalink
add sw_start_leader test
Browse files Browse the repository at this point in the history
Starting a group by having it enabled at open time doesn't work
if your group leader is a software event.
  • Loading branch information
deater committed Jan 29, 2013
1 parent c27f1c4 commit 8a43f3e
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
29 January 2012
+ Add sw_start_leader test

27 November 2012
+ Add simul_oneshot_group_overflow test
+ Release version 0.27
Expand Down
17 changes: 17 additions & 0 deletions corner_cases/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ all: \
reset_leader \
sampled_notleader_refresh \
signal_after_exec \
sw_start_leader \
wrong_size_enospc \


Expand Down Expand Up @@ -136,6 +137,21 @@ signal_after_exec: signal_after_exec.o \
signal_after_exec.o: signal_after_exec.c
$(CC) $(CFLAGS) -c signal_after_exec.c

###

sw_start_leader: sw_start_leader.o \
../lib/perf_helpers.o \
../lib/test_utils.o \
../lib/instructions_testcode.o
$(CC) $(LFLAGS) -o sw_start_leader sw_start_leader.o \
../lib/perf_helpers.o \
../lib/test_utils.o \
../lib/instructions_testcode.o

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



###

Expand Down Expand Up @@ -179,5 +195,6 @@ clean:
overflow_requires_mmap \
reset_leader \
sampled_notleader_refresh \
sw_start_leader \
signal_after_exec \
wrong_size_enospc
241 changes: 241 additions & 0 deletions corner_cases/sw_start_leader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/* sw_start_leader.c */
/* by Vince Weaver vincent.weaver _at_ maine.edu */

/* Test if starting a group (by having the group leader enabled */
/* at event creation time) of mixed sw/hw events works if the */
/* group leader is a software event. */
/* Andreas Hollmann reported this as a problem on the */
/* linux-perf-users list */

/* Bug exists through at least Linux 3.7 */


#define _GNU_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <fcntl.h>

#include <sys/ioctl.h>


#include "perf_event.h"
#include "test_utils.h"
#include "perf_helpers.h"
#include "instructions_testcode.h"


#define EVENTS 3

#define READ_SIZE (EVENTS + 1)

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

int fd[EVENTS],ret,quiet;
int result;
int read_result;
long long count[READ_SIZE];
int i;

struct perf_event_attr pe[EVENTS];

char test_string[]="Testing start with sw event group leader...";

quiet=test_quiet();

if (!quiet) {
printf("Testing if starting a group works in the group leader "
"is a software event.\n");
}


/******************************/
/* TEST 1: */
/* hw-event as leader */
/******************************/

/* setup instruction event, group leader */

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

pe[0].type=PERF_TYPE_HARDWARE;
pe[0].size=sizeof(struct perf_event_attr);
pe[0].config=PERF_COUNT_HW_CPU_CYCLES;
//pe[0].disabled=1;
pe[0].exclude_kernel=1;
pe[0].read_format=PERF_FORMAT_GROUP;

fd[0]=perf_event_open(&pe[0],0,-1,-1,0);
if (fd[0]<0) {
fprintf(stderr,"Error opening\n");
test_fail(test_string);
exit(1);
}

/* setup cycles event, group child */

memset(&pe[1],0,sizeof(struct perf_event_attr));
pe[1].type=PERF_TYPE_SOFTWARE;
pe[1].size=sizeof(struct perf_event_attr);
pe[1].config=PERF_COUNT_SW_CPU_CLOCK;
pe[1].disabled=0;
pe[1].exclude_kernel=1;

fd[1]=perf_event_open(&pe[1],0,-1,fd[0],0);
if (fd[1]<0) {
fprintf(stderr,"Error opening\n");
test_fail(test_string);
exit(1);
}

/* setup cycles event, group child */

memset(&pe[2],0,sizeof(struct perf_event_attr));

pe[2].type=PERF_TYPE_SOFTWARE;
pe[2].size=sizeof(struct perf_event_attr);
pe[2].config=PERF_COUNT_SW_TASK_CLOCK;
pe[2].disabled=0;
pe[2].exclude_kernel=1;

fd[2]=perf_event_open(&pe[2],0,-1,fd[0],0);
if (fd[2]<0) {
fprintf(stderr,"Error opening\n");
test_fail(test_string);
exit(1);
}

// ioctl(fd[0], PERF_EVENT_IOC_RESET, 0);
// ioctl(fd[0], PERF_EVENT_IOC_ENABLE,0);

result=instructions_million();
if (result==CODE_UNIMPLEMENTED) printf("Warning, no million\n");

ioctl(fd[0], PERF_EVENT_IOC_DISABLE,0);

read_result=read(fd[0],&count,sizeof(long long)*READ_SIZE);
if (read_result!=sizeof(long long)*READ_SIZE) {
printf("Unexpected read size\n");
}

if (!quiet) {
printf("Run with HW leader\n");
for(i=0;i<count[0];i++) {
printf("\t%i Counted %lld\n",i,count[1+i]);
}
}

for(i=0;i<EVENTS;i++) {
if (count[i]==0) {
fprintf(stderr,"Counter %d did not start as expected\n",i);
test_fail(test_string);
}
}

for(i=0;i<EVENTS;i++) {
close(fd[i]);
}

/******************************/
/* TEST 2: */
/* sw-event as leader */
/******************************/

/* setup instruction event, group leader */

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

pe[0].type=PERF_TYPE_SOFTWARE;
pe[0].size=sizeof(struct perf_event_attr);
pe[0].config=PERF_COUNT_SW_CPU_CLOCK ;
//pe[0].disabled=1;
pe[0].exclude_kernel=1;
pe[0].read_format=PERF_FORMAT_GROUP;

fd[0]=perf_event_open(&pe[0],0,-1,-1,0);
if (fd[0]<0) {
fprintf(stderr,"Error opening\n");
test_fail(test_string);
exit(1);
}

/* setup cycles event, group child */

memset(&pe[1],0,sizeof(struct perf_event_attr));

pe[1].type=PERF_TYPE_SOFTWARE;
pe[1].size=sizeof(struct perf_event_attr);
pe[1].config=PERF_COUNT_SW_TASK_CLOCK;
pe[1].disabled=0;
pe[1].exclude_kernel=1;

fd[1]=perf_event_open(&pe[1],0,-1,fd[0],0);
if (fd[1]<0) {
fprintf(stderr,"Error opening\n");
test_fail(test_string);
exit(1);
}

/* setup cycles event, group child */

memset(&pe[2],0,sizeof(struct perf_event_attr));

pe[2].type=PERF_TYPE_HARDWARE;
pe[2].size=sizeof(struct perf_event_attr);
pe[2].config=PERF_COUNT_HW_CPU_CYCLES;
pe[2].disabled=0;
pe[2].exclude_kernel=1;

fd[2]=perf_event_open(&pe[2],0,-1,fd[0],0);
if (fd[2]<0) {
fprintf(stderr,"Error opening\n");
test_fail(test_string);
exit(1);
}

// ioctl(fd[0], PERF_EVENT_IOC_RESET, 0);
// ioctl(fd[0], PERF_EVENT_IOC_ENABLE,0);

result=instructions_million();
if (result==CODE_UNIMPLEMENTED) printf("Warning, no million\n");

ioctl(fd[0], PERF_EVENT_IOC_DISABLE,0);

read_result=read(fd[0],&count,sizeof(long long)*READ_SIZE);
if (read_result!=sizeof(long long)*READ_SIZE) {
printf("Unexpected read size\n");
}

if (!quiet) {
printf("Second run, with SW group leader\n");
for(i=0;i<count[0];i++) {
printf("\t%i Counted %lld\n",i,count[1+i]);
}
}

read_result=read(fd[0],&count,sizeof(long long)*READ_SIZE);
if (read_result!=sizeof(long long)*READ_SIZE) {
printf("Unexpected read size\n");
}

for(i=0;i<EVENTS;i++) {
if (count[i]==0) {
fprintf(stderr,"Counter %d did not start as expected\n",i);
test_fail(test_string);
}
}


for(i=0;i<EVENTS;i++) {
close(fd[i]);
}

(void) ret;

test_pass(test_string);

return 0;
}
4 changes: 4 additions & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ echo "* Checking bugs that PAPI has to work around"
./bugs/check_papi_multiplexing
./bugs/check_multiplexing

echo
echo "* Checking other bugs"
./corner_cases/sw_start_leader

echo
echo "* Checking bugs that can silently produce wrong results"
./validation/check_constraints
Expand Down

0 comments on commit 8a43f3e

Please sign in to comment.