~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/perf_events/watermark_signal.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #define _GNU_SOURCE
  3 
  4 #include <errno.h>
  5 #include <fcntl.h>
  6 #include <linux/perf_event.h>
  7 #include <stddef.h>
  8 #include <sched.h>
  9 #include <signal.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <sys/ioctl.h>
 13 #include <sys/mman.h>
 14 #include <sys/syscall.h>
 15 #include <sys/wait.h>
 16 #include <unistd.h>
 17 
 18 #include "../kselftest_harness.h"
 19 
 20 #define __maybe_unused __attribute__((__unused__))
 21 
 22 static int sigio_count;
 23 
 24 static void handle_sigio(int signum __maybe_unused,
 25                          siginfo_t *oh __maybe_unused,
 26                          void *uc __maybe_unused)
 27 {
 28         ++sigio_count;
 29 }
 30 
 31 static void do_child(void)
 32 {
 33         raise(SIGSTOP);
 34 
 35         for (int i = 0; i < 20; ++i)
 36                 sleep(1);
 37 
 38         raise(SIGSTOP);
 39 
 40         exit(0);
 41 }
 42 
 43 TEST(watermark_signal)
 44 {
 45         struct perf_event_attr attr;
 46         struct perf_event_mmap_page *p = NULL;
 47         struct sigaction previous_sigio, sigio = { 0 };
 48         pid_t child = -1;
 49         int child_status;
 50         int fd = -1;
 51         long page_size = sysconf(_SC_PAGE_SIZE);
 52 
 53         sigio.sa_sigaction = handle_sigio;
 54         EXPECT_EQ(sigaction(SIGIO, &sigio, &previous_sigio), 0);
 55 
 56         memset(&attr, 0, sizeof(attr));
 57         attr.size = sizeof(attr);
 58         attr.type = PERF_TYPE_SOFTWARE;
 59         attr.config = PERF_COUNT_SW_DUMMY;
 60         attr.sample_period = 1;
 61         attr.disabled = 1;
 62         attr.watermark = 1;
 63         attr.context_switch = 1;
 64         attr.wakeup_watermark = 1;
 65 
 66         child = fork();
 67         EXPECT_GE(child, 0);
 68         if (child == 0)
 69                 do_child();
 70         else if (child < 0) {
 71                 perror("fork()");
 72                 goto cleanup;
 73         }
 74 
 75         if (waitpid(child, &child_status, WSTOPPED) != child ||
 76             !(WIFSTOPPED(child_status) && WSTOPSIG(child_status) == SIGSTOP)) {
 77                 fprintf(stderr,
 78                         "failed to sycnhronize with child errno=%d status=%x\n",
 79                         errno,
 80                         child_status);
 81                 goto cleanup;
 82         }
 83 
 84         fd = syscall(__NR_perf_event_open, &attr, child, -1, -1,
 85                      PERF_FLAG_FD_CLOEXEC);
 86         if (fd < 0) {
 87                 fprintf(stderr, "failed opening event %llx\n", attr.config);
 88                 goto cleanup;
 89         }
 90 
 91         if (fcntl(fd, F_SETFL, FASYNC)) {
 92                 perror("F_SETFL FASYNC");
 93                 goto cleanup;
 94         }
 95 
 96         if (fcntl(fd, F_SETOWN, getpid())) {
 97                 perror("F_SETOWN getpid()");
 98                 goto cleanup;
 99         }
100 
101         if (fcntl(fd, F_SETSIG, SIGIO)) {
102                 perror("F_SETSIG SIGIO");
103                 goto cleanup;
104         }
105 
106         p = mmap(NULL, 2 * page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
107         if (p == NULL) {
108                 perror("mmap");
109                 goto cleanup;
110         }
111 
112         if (ioctl(fd, PERF_EVENT_IOC_ENABLE, 0)) {
113                 perror("PERF_EVENT_IOC_ENABLE");
114                 goto cleanup;
115         }
116 
117         if (kill(child, SIGCONT) < 0) {
118                 perror("SIGCONT");
119                 goto cleanup;
120         }
121 
122         if (waitpid(child, &child_status, WSTOPPED) != -1 || errno != EINTR)
123                 fprintf(stderr,
124                         "expected SIGIO to terminate wait errno=%d status=%x\n%d",
125                         errno,
126                         child_status,
127                         sigio_count);
128 
129         EXPECT_GE(sigio_count, 1);
130 
131 cleanup:
132         if (p != NULL)
133                 munmap(p, 2 * page_size);
134 
135         if (fd >= 0)
136                 close(fd);
137 
138         if (child > 0) {
139                 kill(child, SIGKILL);
140                 waitpid(child, NULL, 0);
141         }
142 
143         sigaction(SIGIO, &previous_sigio, NULL);
144 }
145 
146 TEST_HARNESS_MAIN
147 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php