144 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Originally done by Vince Weaver <vincent.weaver@maine.edu> for4 * perf_event_tests (git://github.com/deater/perf_event_tests)5 */6 7/*8 * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select9 * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.10 */11#define __SANE_USERSPACE_TYPES__12 13#include <stdlib.h>14#include <stdio.h>15#include <unistd.h>16#include <string.h>17#include <sys/ioctl.h>18#include <time.h>19#include <fcntl.h>20#include <signal.h>21#include <sys/mman.h>22#include <linux/compiler.h>23#include <linux/hw_breakpoint.h>24 25#include "tests.h"26#include "debug.h"27#include "event.h"28#include "parse-events.h"29#include "../perf-sys.h"30#include "cloexec.h"31 32static int overflows;33 34static noinline int test_function(void)35{36 return time(NULL);37}38 39static void sig_handler(int signum __maybe_unused,40 siginfo_t *oh __maybe_unused,41 void *uc __maybe_unused)42{43 overflows++;44}45 46static long long bp_count(int fd)47{48 long long count;49 int ret;50 51 ret = read(fd, &count, sizeof(long long));52 if (ret != sizeof(long long)) {53 pr_debug("failed to read: %d\n", ret);54 return TEST_FAIL;55 }56 57 return count;58}59 60#define EXECUTIONS 1000061#define THRESHOLD 10062 63static int test__bp_signal_overflow(struct test_suite *test __maybe_unused, int subtest __maybe_unused)64{65 struct perf_event_attr pe;66 struct sigaction sa;67 long long count;68 int fd, i, fails = 0;69 70 if (!BP_SIGNAL_IS_SUPPORTED) {71 pr_debug("Test not supported on this architecture");72 return TEST_SKIP;73 }74 75 /* setup SIGIO signal handler */76 memset(&sa, 0, sizeof(struct sigaction));77 sa.sa_sigaction = (void *) sig_handler;78 sa.sa_flags = SA_SIGINFO;79 80 if (sigaction(SIGIO, &sa, NULL) < 0) {81 pr_debug("failed setting up signal handler\n");82 return TEST_FAIL;83 }84 85 memset(&pe, 0, sizeof(struct perf_event_attr));86 pe.type = PERF_TYPE_BREAKPOINT;87 pe.size = sizeof(struct perf_event_attr);88 89 pe.config = 0;90 pe.bp_type = HW_BREAKPOINT_X;91 pe.bp_addr = (unsigned long) test_function;92 pe.bp_len = default_breakpoint_len();93 94 pe.sample_period = THRESHOLD;95 pe.sample_type = PERF_SAMPLE_IP;96 pe.wakeup_events = 1;97 98 pe.disabled = 1;99 pe.exclude_kernel = 1;100 pe.exclude_hv = 1;101 102 fd = sys_perf_event_open(&pe, 0, -1, -1,103 perf_event_open_cloexec_flag());104 if (fd < 0) {105 pr_debug("failed opening event %llx\n", pe.config);106 return TEST_FAIL;107 }108 109 fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);110 fcntl(fd, F_SETSIG, SIGIO);111 fcntl(fd, F_SETOWN, getpid());112 113 ioctl(fd, PERF_EVENT_IOC_RESET, 0);114 ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);115 116 for (i = 0; i < EXECUTIONS; i++)117 test_function();118 119 ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);120 121 count = bp_count(fd);122 123 close(fd);124 125 pr_debug("count %lld, overflow %d\n",126 count, overflows);127 128 if (count != EXECUTIONS) {129 pr_debug("\tWrong number of executions %lld != %d\n",130 count, EXECUTIONS);131 fails++;132 }133 134 if (overflows != EXECUTIONS / THRESHOLD) {135 pr_debug("\tWrong number of overflows %d != %d\n",136 overflows, EXECUTIONS / THRESHOLD);137 fails++;138 }139 140 return fails ? TEST_FAIL : TEST_OK;141}142 143DEFINE_SUITE("Breakpoint overflow sampling", bp_signal_overflow);144