perf: overflow test
Change-Id: Ic7aa0d99ae9a5b7d3ce4436129a360275e6937ca refs: #1358
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,6 +15,7 @@ CMakeCache.txt
|
||||
Makefile
|
||||
!test/*/*/Makefile
|
||||
!test/signalonfork+wait/Makefile
|
||||
!test/perf_overflow/Makefile
|
||||
!test/*/*/*.cmd
|
||||
Kbuild
|
||||
cmake_install.cmake
|
||||
|
||||
23
test/perf_overflow/Makefile
Normal file
23
test/perf_overflow/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
# Makefile COPYRIGHT FUJITSU LIMITED 2019
|
||||
CC := ${CROSS_COMPILE}gcc
|
||||
|
||||
CFLAGS += -Wall -O0 -ggdb3
|
||||
|
||||
TARGET := perf_overflow
|
||||
SRC := $(wildcard *.c)
|
||||
OBJ := $(SRC:.c=.o)
|
||||
DEP := $(SRC:.c=.d)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -MMD -MP -c $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) $(OBJ) $(DEP) $(TARGET)
|
||||
|
||||
-include $(DEP)
|
||||
35
test/perf_overflow/README
Normal file
35
test/perf_overflow/README
Normal file
@ -0,0 +1,35 @@
|
||||
==========
|
||||
How to run
|
||||
==========
|
||||
|
||||
(1) Build McKernel
|
||||
(2) cd <mckernel>/test/perf_overflow
|
||||
(3) make
|
||||
(4) sh run.sh
|
||||
|
||||
============
|
||||
What to test
|
||||
============
|
||||
|
||||
Test overflow handling of performance counter.
|
||||
The steps of the test programs are as follows:
|
||||
(1) Starts counting with the initial counter value set to -30
|
||||
(2) Executes 40 nops
|
||||
(3) Repeat (4)-(5) with the commands specified by the test-case
|
||||
(4) Executes sys_read or sys_ioctl(PERF_EVENT_IOC_RESET) or sys_ioctl(PERF_EVENT_IOC_REFRESH)
|
||||
(5) Executes 40 nops
|
||||
(6) Checks if the counter value read in (4) is the same as Linux run
|
||||
|
||||
|
||||
000) count the number of executions of nop
|
||||
001) read counter while counting nop
|
||||
002) reset counter while nop counting
|
||||
003) refresh counter while counting nop
|
||||
010) read, reset, and refresh counter while counting nop
|
||||
011) read, read, and refresh counter while counting nop
|
||||
012) reset, reset, and read counter while counting nop
|
||||
013) refresh, refresh, and reset counter while counting nop
|
||||
014) refresh, read, and read counter while counting nop
|
||||
|
||||
--
|
||||
README COPYRIGHT FUJITSU LIMITED 2019
|
||||
154
test/perf_overflow/combination_test.c
Normal file
154
test/perf_overflow/combination_test.c
Normal file
@ -0,0 +1,154 @@
|
||||
/* combination_test.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "combination_test.h"
|
||||
|
||||
//
|
||||
// main
|
||||
//
|
||||
static int combination_test(struct command_set *cmd_set)
|
||||
{
|
||||
struct perf_event_attr pe;
|
||||
long long lest_count;
|
||||
int ret = -1;
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
ret = init_perf_event_attr(&pe);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s : Failed to init_perf_event_attr.\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = perf_event_open(&pe, 0, -1, -1, 0);
|
||||
if (fd == -1) {
|
||||
perror("pef_event_open");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
if (ret < 0) {
|
||||
perror("ioctl(PERF_EVENT_IOC_RESET)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_ENABLE, 0);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_ENABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
for (i = 0; i < cmd_set->nr_cmds; i++) {
|
||||
struct command *cmd = &cmd_set->cmds[i];
|
||||
|
||||
cmd->do_cmd(fd, cmd->args);
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
}
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_DISABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < cmd_set->nr_cmds; i++) {
|
||||
struct command *cmd = &cmd_set->cmds[i];
|
||||
|
||||
cmd->print(cmd->args);
|
||||
}
|
||||
|
||||
ret = read(fd, &lest_count, sizeof(lest_count));
|
||||
if (ret < 0) {
|
||||
perror("read(lest_count)");
|
||||
goto out;
|
||||
}
|
||||
printf("---------\n"
|
||||
"sys_read: %lld\n", lest_count);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int combination_main(int argc, char **argv)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
int opt;
|
||||
char *input_commands = NULL;
|
||||
struct command_set cmd_set = {0};
|
||||
|
||||
// parse args
|
||||
while ((opt = getopt(argc, argv, "c:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
input_commands = optarg;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (input_commands == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s : combination test requires -c option.\n",
|
||||
__func__);
|
||||
print_usage();
|
||||
goto out;
|
||||
}
|
||||
|
||||
// build command
|
||||
for (i = 0; i <= MAX_COMBINATION; i++) {
|
||||
const char *cmd = strtok(input_commands, ",");
|
||||
|
||||
input_commands = NULL;
|
||||
if (cmd == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_COMBINATION) {
|
||||
fprintf(stderr,
|
||||
"%s : Too many arguments to option '-c'.\n",
|
||||
__func__);
|
||||
goto release_out;
|
||||
}
|
||||
|
||||
if (build_command(cmd, &cmd_set.cmds[i]) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s : Incorrect command[%s].\n",
|
||||
__func__, cmd);
|
||||
print_usage();
|
||||
goto release_out;
|
||||
}
|
||||
}
|
||||
cmd_set.nr_cmds = i;
|
||||
|
||||
// run
|
||||
ret = combination_test(&cmd_set);
|
||||
|
||||
// release command
|
||||
release_out:
|
||||
for (i = 0; i < cmd_set.nr_cmds; i++) {
|
||||
struct command *cmd = &cmd_set.cmds[i];
|
||||
|
||||
cmd->release(cmd);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
9
test/perf_overflow/combination_test.h
Normal file
9
test/perf_overflow/combination_test.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* combination_test.h COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#ifndef _COMBINATION_TEST_H_
|
||||
#define _COMBINATION_TEST_H_
|
||||
|
||||
#include "perf_common.h"
|
||||
|
||||
int combination_main(int argc, char **argv);
|
||||
|
||||
#endif /* _COMBINATION_TEST_H_ */
|
||||
64
test/perf_overflow/main.c
Normal file
64
test/perf_overflow/main.c
Normal file
@ -0,0 +1,64 @@
|
||||
/* main.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "simple_test.h"
|
||||
#include "read_test.h"
|
||||
#include "reset_test.h"
|
||||
#include "refresh_test.h"
|
||||
#include "combination_test.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = -1;
|
||||
int test_num = -1;
|
||||
char *endptr = NULL;
|
||||
|
||||
the_app = argv[0];
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,
|
||||
"%s : Incorrect number of arguments.\n",
|
||||
__func__);
|
||||
print_usage();
|
||||
goto out;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
test_num = strtol(argv[1], &endptr, 0);
|
||||
if (errno != 0 ||
|
||||
*endptr != '\0' ||
|
||||
(test_num < INT_MIN || INT_MAX < test_num)) {
|
||||
fprintf(stderr, "%s : Failed to get test_num.\n"
|
||||
"error code : %d\n", __func__, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (test_num) {
|
||||
case 1:
|
||||
ret = simple_test();
|
||||
break;
|
||||
case 2:
|
||||
ret = read_test();
|
||||
break;
|
||||
case 3:
|
||||
ret = reset_test();
|
||||
break;
|
||||
case 4:
|
||||
ret = refresh_test();
|
||||
break;
|
||||
case 5:
|
||||
argc--;
|
||||
argv[1] = argv[0];
|
||||
ret = combination_main(argc, &argv[1]);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s : Incorrect test_num.\n", __func__);
|
||||
print_usage();
|
||||
break;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
213
test/perf_overflow/perf_common.c
Normal file
213
test/perf_overflow/perf_common.c
Normal file
@ -0,0 +1,213 @@
|
||||
/* perf_common.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "perf_common.h"
|
||||
|
||||
const char *the_app;
|
||||
|
||||
//
|
||||
// usage
|
||||
//
|
||||
void print_usage(void)
|
||||
{
|
||||
printf("usage : %s [test_num]\n"
|
||||
"test_num :\n"
|
||||
" 1 simple_test\n"
|
||||
" 2 read_test\n"
|
||||
" 3 reset_test\n"
|
||||
" 4 refresh_test\n"
|
||||
" 5 combination_test\n"
|
||||
"\n"
|
||||
"combination_test :\n"
|
||||
" perf_test 5 -c [ctrl1,ctrl2...]\n"
|
||||
"ex) perf_test 5 -c READ,RESET,REFRESH\n",
|
||||
the_app
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// system call
|
||||
//
|
||||
long perf_event_open(struct perf_event_attr *event_attr, pid_t pid,
|
||||
int cpu, int group_fd, unsigned long flags)
|
||||
{
|
||||
int ret = syscall(__NR_perf_event_open, event_attr, pid, cpu,
|
||||
group_fd, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int init_perf_event_attr(struct perf_event_attr *event_attr)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (event_attr == NULL) {
|
||||
goto out;
|
||||
}
|
||||
memset(event_attr, 0, sizeof(struct perf_event_attr));
|
||||
event_attr->type = PERF_TYPE_HARDWARE;
|
||||
event_attr->size = sizeof(struct perf_event_attr);
|
||||
event_attr->config = PERF_COUNT_HW_INSTRUCTIONS;
|
||||
event_attr->sample_period = SAMPLE_PERIOD;
|
||||
event_attr->disabled = 1;
|
||||
event_attr->exclude_kernel = 1;
|
||||
event_attr->exclude_hv = 1;
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long system_call3(long syscall_number, long arg0, long arg1, long arg2)
|
||||
{
|
||||
long ret;
|
||||
#if defined(__x86_64__)
|
||||
asm volatile ("syscall"
|
||||
: "=a" (ret)
|
||||
: "a" (syscall_number), "D" (arg0), "S" (arg1), "d" (arg2)
|
||||
: "rcx", "r11", "memory");
|
||||
#elif defined(__aarch64__)
|
||||
asm volatile(
|
||||
"mov x8, %1;"
|
||||
"mov x0, %2;"
|
||||
"mov x1, %3;"
|
||||
"mov x2, %4;"
|
||||
"svc #0x0;"
|
||||
"mov %0, x0;"
|
||||
: "=r" (ret)
|
||||
: "r" (syscall_number),
|
||||
"r" (arg0), "r" (arg1), "r" (arg2));
|
||||
#else
|
||||
# error not supported architecture.
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int asm_ioctl3(int fd, unsigned long arg1, unsigned long arg2)
|
||||
{
|
||||
return system_call3(__NR_ioctl, fd, arg1, arg2);
|
||||
}
|
||||
|
||||
int asm_read(int fd, void *buf, size_t size)
|
||||
{
|
||||
return system_call3(__NR_read, fd, (unsigned long)buf, size);
|
||||
}
|
||||
|
||||
//
|
||||
// command
|
||||
//
|
||||
|
||||
// sys_read command
|
||||
struct sys_read_arg {
|
||||
long long count;
|
||||
};
|
||||
|
||||
static int sys_read(int fd, void *_args)
|
||||
{
|
||||
struct sys_read_arg *args = _args;
|
||||
int ret = asm_read(fd, &args->count, sizeof(args->count));
|
||||
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
perror("sys_read");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_sys_read(void *_args)
|
||||
{
|
||||
struct sys_read_arg *args = _args;
|
||||
|
||||
printf("sys_read: %lld\n", args->count);
|
||||
}
|
||||
|
||||
static void release_sys_read_command(struct command *cmd)
|
||||
{
|
||||
free(cmd->args);
|
||||
cmd->args = NULL;
|
||||
}
|
||||
|
||||
static void build_sys_read_command(struct command *cmd)
|
||||
{
|
||||
cmd->do_cmd = sys_read;
|
||||
cmd->args = calloc(sizeof(struct sys_read_arg), 1);
|
||||
cmd->release = release_sys_read_command;
|
||||
cmd->print = print_sys_read;
|
||||
}
|
||||
|
||||
// perf_event_ioc_reset command
|
||||
static int perf_event_ioc_reset(int fd, void *_args)
|
||||
{
|
||||
int ret = asm_ioctl3(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
perror("sys_ioctl: reset");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_perf_event_ioc_reset(void *cmd)
|
||||
{
|
||||
printf("%s:\n", __func__);
|
||||
}
|
||||
|
||||
static void release_perf_event_ioc_reset(struct command *cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void build_perf_event_ioc_reset(struct command *cmd)
|
||||
{
|
||||
cmd->do_cmd = perf_event_ioc_reset;
|
||||
cmd->args = NULL;
|
||||
cmd->release = release_perf_event_ioc_reset;
|
||||
cmd->print = print_perf_event_ioc_reset;
|
||||
}
|
||||
|
||||
// perf_event_ioc_refresh command
|
||||
static int perf_event_ioc_refresh(int fd, void *_args)
|
||||
{
|
||||
int ret = asm_ioctl3(fd, PERF_EVENT_IOC_REFRESH, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
perror("sys_ioctl: refresh");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_perf_event_ioc_refresh(void *cmd)
|
||||
{
|
||||
printf("%s:\n", __func__);
|
||||
}
|
||||
|
||||
static void release_perf_event_ioc_refresh(struct command *cmd)
|
||||
{
|
||||
}
|
||||
|
||||
static void build_perf_event_ioc_refresh(struct command *cmd)
|
||||
{
|
||||
cmd->do_cmd = perf_event_ioc_refresh;
|
||||
cmd->args = NULL;
|
||||
cmd->release = release_perf_event_ioc_refresh;
|
||||
cmd->print = print_perf_event_ioc_refresh;
|
||||
}
|
||||
|
||||
// command factory
|
||||
int build_command(const char *cmd_src, struct command *cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (strcmp(cmd_src, "READ") == 0) {
|
||||
build_sys_read_command(cmd);
|
||||
}
|
||||
else if (strcmp(cmd_src, "RESET") == 0) {
|
||||
build_perf_event_ioc_reset(cmd);
|
||||
}
|
||||
else if (strcmp(cmd_src, "REFRESH") == 0) {
|
||||
build_perf_event_ioc_refresh(cmd);
|
||||
}
|
||||
else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
47
test/perf_overflow/perf_common.h
Normal file
47
test/perf_overflow/perf_common.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* perf_common.h COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#ifndef _PERF_COMMON_H_
|
||||
#define _PERF_COMMON_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
#define SAMPLE_PERIOD 30
|
||||
|
||||
#define nop10 do { \
|
||||
asm volatile("nop;nop;nop;nop;nop;" \
|
||||
"nop;nop;nop;nop;nop"); \
|
||||
} while (0)
|
||||
|
||||
//usage
|
||||
extern const char *the_app;
|
||||
void print_usage(void);
|
||||
|
||||
//system call
|
||||
long perf_event_open(struct perf_event_attr *event_attr, pid_t pid,
|
||||
int cpu, int group_fd, unsigned long flags);
|
||||
int init_perf_event_attr(struct perf_event_attr *event_attr);
|
||||
int asm_ioctl3(int fd, unsigned long arg1, unsigned long arg2);
|
||||
int asm_read(int fd, void *buf, size_t size);
|
||||
|
||||
//command
|
||||
struct command {
|
||||
void *args;
|
||||
void (*release)(struct command *cmd);
|
||||
int (*do_cmd)(int fd, void *args);
|
||||
void (*print)(void *args);
|
||||
};
|
||||
|
||||
#define MAX_COMBINATION 256
|
||||
struct command_set {
|
||||
int nr_cmds;
|
||||
struct command cmds[MAX_COMBINATION];
|
||||
};
|
||||
int build_command(const char *cmd_src, struct command *cmd);
|
||||
|
||||
#endif /* _PERF_COMMON_H_ */
|
||||
69
test/perf_overflow/read_test.c
Normal file
69
test/perf_overflow/read_test.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* read_test.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "read_test.h"
|
||||
|
||||
int read_test(void)
|
||||
{
|
||||
struct perf_event_attr pe;
|
||||
long long count = 0;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
|
||||
ret = init_perf_event_attr(&pe);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s : Failed to init_perf_event_attr.\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = perf_event_open(&pe, 0, -1, -1, 0);
|
||||
if (fd == -1) {
|
||||
ret = errno;
|
||||
perror("perf_event_open");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
if (ret < 0) {
|
||||
perror("ioctl(PERF_EVENT_IOC_RESET)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_ENABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_ENABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
ret = asm_read(fd, &count, sizeof(long long));
|
||||
if (ret < 0) {
|
||||
perror("asm_read");
|
||||
}
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_DISABLE)");
|
||||
}
|
||||
printf("Used %lld instructions\n", count);
|
||||
|
||||
ret = read(fd, &count, sizeof(long long));
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
}
|
||||
printf("Used %lld instructions\n", count);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
9
test/perf_overflow/read_test.h
Normal file
9
test/perf_overflow/read_test.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* read_test.h COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#ifndef _READ_TEST_H_
|
||||
#define _READ_TEST_H_
|
||||
|
||||
#include "perf_common.h"
|
||||
|
||||
int read_test(void);
|
||||
|
||||
#endif /* _READ_TEST_H_ */
|
||||
72
test/perf_overflow/refresh_test.c
Normal file
72
test/perf_overflow/refresh_test.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* refresh_test.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "refresh_test.h"
|
||||
|
||||
int refresh_test(void)
|
||||
{
|
||||
struct perf_event_attr pe;
|
||||
long long count = 0;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
|
||||
ret = init_perf_event_attr(&pe);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s : Failed to init_perf_event_attr.\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = perf_event_open(&pe, 0, -1, -1, 0);
|
||||
if (fd == -1) {
|
||||
ret = errno;
|
||||
perror("perf_event_open");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
if (ret < 0) {
|
||||
perror("ioctl(PERF_EVENT_IOC_RESET)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_ENABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_ENABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_REFRESH, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_REFRESH)");
|
||||
goto out;
|
||||
}
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_DISABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = read(fd, &count, sizeof(long long));
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Used %lld instructions\n", count);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
9
test/perf_overflow/refresh_test.h
Normal file
9
test/perf_overflow/refresh_test.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* refresh_test.h COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#ifndef _REFRESH_TEST_H_
|
||||
#define _REFRESH_TEST_H_
|
||||
|
||||
#include "perf_common.h"
|
||||
|
||||
int refresh_test(void);
|
||||
|
||||
#endif /* _REFRESH_TEST_H_ */
|
||||
71
test/perf_overflow/reset_test.c
Normal file
71
test/perf_overflow/reset_test.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* reset_test.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "refresh_test.h"
|
||||
|
||||
int reset_test(void)
|
||||
{
|
||||
struct perf_event_attr pe;
|
||||
long long count = 0;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
|
||||
ret = init_perf_event_attr(&pe);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s : Failed to init_perf_event_attr.\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = perf_event_open(&pe, 0, -1, -1, 0);
|
||||
if (fd == -1) {
|
||||
fd = errno;
|
||||
perror("perf_event_open");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
if (ret < 0) {
|
||||
perror("ioctl(PERF_EVENT_IOC_RESET)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_ENABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_ENABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_RESET)");
|
||||
}
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_DISABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = read(fd, &count, sizeof(long long));
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Used %lld instructions\n", count);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
9
test/perf_overflow/reset_test.h
Normal file
9
test/perf_overflow/reset_test.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* reset_test.h COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#ifndef _RESET_TEST_H_
|
||||
#define _RESET_TEST_H_
|
||||
|
||||
#include "perf_common.h"
|
||||
|
||||
int reset_test(void);
|
||||
|
||||
#endif /* _RESET_TEST_H_ */
|
||||
12
test/perf_overflow/result.log
Normal file
12
test/perf_overflow/result.log
Normal file
@ -0,0 +1,12 @@
|
||||
[root@hostname perf_overflow]# sh run.sh
|
||||
mcstop+release.sh ... done
|
||||
mcreboot.sh -c 12-59 -m 512M@4 ... done
|
||||
000: OK
|
||||
001: OK
|
||||
002: OK
|
||||
003: OK
|
||||
010: OK
|
||||
011: OK
|
||||
012: OK
|
||||
013: OK
|
||||
014: OK
|
||||
37
test/perf_overflow/run.sh
Normal file
37
test/perf_overflow/run.sh
Normal file
@ -0,0 +1,37 @@
|
||||
#!/bin/env bash
|
||||
# run.sh COPYRIGHT FUJITSU LIMITED 2019
|
||||
test_dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
result_dir="$test_dir/results"
|
||||
|
||||
# read config
|
||||
. "${test_dir}/../common.sh"
|
||||
|
||||
# settings
|
||||
test_bin="$test_dir/perf_overflow"
|
||||
test_cases=`cat << __EOF__
|
||||
000 1
|
||||
001 2
|
||||
002 3
|
||||
003 4
|
||||
010 5 -c READ,RESET,REFRESH
|
||||
011 5 -c READ,READ,REFRESH
|
||||
012 5 -c RESET,RESET,READ
|
||||
013 5 -c REFRESH,REFRESH,RESET
|
||||
014 5 -c REFRESH,READ,READ
|
||||
__EOF__`
|
||||
|
||||
mkdir -p "$result_dir"
|
||||
while read num args
|
||||
do
|
||||
"$test_bin" $args > "$result_dir/${num}.host"
|
||||
"${MCEXEC}" 0 "$test_bin" $args > "$result_dir/${num}.mck"
|
||||
|
||||
diff -q "$result_dir/${num}.host" "$result_dir/${num}.mck"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$num: OK"
|
||||
else
|
||||
echo "$num: NG"
|
||||
fi
|
||||
done <<EOF
|
||||
$test_cases
|
||||
EOF
|
||||
64
test/perf_overflow/simple_test.c
Normal file
64
test/perf_overflow/simple_test.c
Normal file
@ -0,0 +1,64 @@
|
||||
/* simple_test.c COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#include "simple_test.h"
|
||||
|
||||
int simple_test(void)
|
||||
{
|
||||
struct perf_event_attr pe;
|
||||
long long count = 0;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
|
||||
ret = init_perf_event_attr(&pe);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s : Failed to init_perf_event_attr.\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = perf_event_open(&pe, 0, -1, -1, 0);
|
||||
if (fd == -1) {
|
||||
ret = errno;
|
||||
perror("perf_event_open");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, PERF_EVENT_IOC_RESET, 0);
|
||||
if (ret < 0) {
|
||||
perror("ioctl(PERF_EVENT_IOC_RESET)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_ENABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_ENABLE)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
nop10;
|
||||
|
||||
ret = asm_ioctl3(fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (ret < 0) {
|
||||
perror("asm_ioctl(PERF_EVENT_IOC_DISABLE)");
|
||||
}
|
||||
|
||||
ret = read(fd, &count, sizeof(long long));
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
}
|
||||
printf("Used %lld instructions\n", count);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
9
test/perf_overflow/simple_test.h
Normal file
9
test/perf_overflow/simple_test.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* simple_test.h COPYRIGHT FUJITSU LIMITED 2019 */
|
||||
#ifndef _SIMPLE_TEST_H_
|
||||
#define _SIMPLE_TEST_H_
|
||||
|
||||
#include "perf_common.h"
|
||||
|
||||
int simple_test(void);
|
||||
|
||||
#endif /* _SIMPLE_TEST_H_ */
|
||||
Reference in New Issue
Block a user