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

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/send_signal.c

Version: ~ [ linux-5.16-rc1 ] ~ [ linux-5.15.2 ] ~ [ linux-5.14.18 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.79 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.159 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.217 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.255 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.290 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.292 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <test_progs.h>
  3 #include "test_send_signal_kern.skel.h"
  4 
  5 static volatile int sigusr1_received = 0;
  6 
  7 static void sigusr1_handler(int signum)
  8 {
  9         sigusr1_received++;
 10 }
 11 
 12 static void test_send_signal_common(struct perf_event_attr *attr,
 13                                     bool signal_thread,
 14                                     const char *test_name)
 15 {
 16         struct test_send_signal_kern *skel;
 17         int pipe_c2p[2], pipe_p2c[2];
 18         int err = -1, pmu_fd = -1;
 19         __u32 duration = 0;
 20         char buf[256];
 21         pid_t pid;
 22 
 23         if (CHECK(pipe(pipe_c2p), test_name,
 24                   "pipe pipe_c2p error: %s\n", strerror(errno)))
 25                 return;
 26 
 27         if (CHECK(pipe(pipe_p2c), test_name,
 28                   "pipe pipe_p2c error: %s\n", strerror(errno))) {
 29                 close(pipe_c2p[0]);
 30                 close(pipe_c2p[1]);
 31                 return;
 32         }
 33 
 34         pid = fork();
 35         if (CHECK(pid < 0, test_name, "fork error: %s\n", strerror(errno))) {
 36                 close(pipe_c2p[0]);
 37                 close(pipe_c2p[1]);
 38                 close(pipe_p2c[0]);
 39                 close(pipe_p2c[1]);
 40                 return;
 41         }
 42 
 43         if (pid == 0) {
 44                 /* install signal handler and notify parent */
 45                 signal(SIGUSR1, sigusr1_handler);
 46 
 47                 close(pipe_c2p[0]); /* close read */
 48                 close(pipe_p2c[1]); /* close write */
 49 
 50                 /* notify parent signal handler is installed */
 51                 CHECK(write(pipe_c2p[1], buf, 1) != 1, "pipe_write", "err %d\n", -errno);
 52 
 53                 /* make sure parent enabled bpf program to send_signal */
 54                 CHECK(read(pipe_p2c[0], buf, 1) != 1, "pipe_read", "err %d\n", -errno);
 55 
 56                 /* wait a little for signal handler */
 57                 sleep(1);
 58 
 59                 buf[0] = sigusr1_received ? '2' : '';
 60                 CHECK(write(pipe_c2p[1], buf, 1) != 1, "pipe_write", "err %d\n", -errno);
 61 
 62                 /* wait for parent notification and exit */
 63                 CHECK(read(pipe_p2c[0], buf, 1) != 1, "pipe_read", "err %d\n", -errno);
 64 
 65                 close(pipe_c2p[1]);
 66                 close(pipe_p2c[0]);
 67                 exit(0);
 68         }
 69 
 70         close(pipe_c2p[1]); /* close write */
 71         close(pipe_p2c[0]); /* close read */
 72 
 73         skel = test_send_signal_kern__open_and_load();
 74         if (CHECK(!skel, "skel_open_and_load", "skeleton open_and_load failed\n"))
 75                 goto skel_open_load_failure;
 76 
 77         if (!attr) {
 78                 err = test_send_signal_kern__attach(skel);
 79                 if (CHECK(err, "skel_attach", "skeleton attach failed\n")) {
 80                         err = -1;
 81                         goto destroy_skel;
 82                 }
 83         } else {
 84                 pmu_fd = syscall(__NR_perf_event_open, attr, pid, -1,
 85                                  -1 /* group id */, 0 /* flags */);
 86                 if (CHECK(pmu_fd < 0, test_name, "perf_event_open error: %s\n",
 87                         strerror(errno))) {
 88                         err = -1;
 89                         goto destroy_skel;
 90                 }
 91 
 92                 skel->links.send_signal_perf =
 93                         bpf_program__attach_perf_event(skel->progs.send_signal_perf, pmu_fd);
 94                 if (CHECK(IS_ERR(skel->links.send_signal_perf), "attach_perf_event",
 95                           "err %ld\n", PTR_ERR(skel->links.send_signal_perf)))
 96                         goto disable_pmu;
 97         }
 98 
 99         /* wait until child signal handler installed */
100         CHECK(read(pipe_c2p[0], buf, 1) != 1, "pipe_read", "err %d\n", -errno);
101 
102         /* trigger the bpf send_signal */
103         skel->bss->pid = pid;
104         skel->bss->sig = SIGUSR1;
105         skel->bss->signal_thread = signal_thread;
106 
107         /* notify child that bpf program can send_signal now */
108         CHECK(write(pipe_p2c[1], buf, 1) != 1, "pipe_write", "err %d\n", -errno);
109 
110         /* wait for result */
111         err = read(pipe_c2p[0], buf, 1);
112         if (CHECK(err < 0, test_name, "reading pipe error: %s\n", strerror(errno)))
113                 goto disable_pmu;
114         if (CHECK(err == 0, test_name, "reading pipe error: size 0\n")) {
115                 err = -1;
116                 goto disable_pmu;
117         }
118 
119         CHECK(buf[0] != '2', test_name, "incorrect result\n");
120 
121         /* notify child safe to exit */
122         CHECK(write(pipe_p2c[1], buf, 1) != 1, "pipe_write", "err %d\n", -errno);
123 
124 disable_pmu:
125         close(pmu_fd);
126 destroy_skel:
127         test_send_signal_kern__destroy(skel);
128 skel_open_load_failure:
129         close(pipe_c2p[0]);
130         close(pipe_p2c[1]);
131         wait(NULL);
132 }
133 
134 static void test_send_signal_tracepoint(bool signal_thread)
135 {
136         test_send_signal_common(NULL, signal_thread, "tracepoint");
137 }
138 
139 static void test_send_signal_perf(bool signal_thread)
140 {
141         struct perf_event_attr attr = {
142                 .sample_period = 1,
143                 .type = PERF_TYPE_SOFTWARE,
144                 .config = PERF_COUNT_SW_CPU_CLOCK,
145         };
146 
147         test_send_signal_common(&attr, signal_thread, "perf_sw_event");
148 }
149 
150 static void test_send_signal_nmi(bool signal_thread)
151 {
152         struct perf_event_attr attr = {
153                 .sample_period = 1,
154                 .type = PERF_TYPE_HARDWARE,
155                 .config = PERF_COUNT_HW_CPU_CYCLES,
156         };
157         int pmu_fd;
158 
159         /* Some setups (e.g. virtual machines) might run with hardware
160          * perf events disabled. If this is the case, skip this test.
161          */
162         pmu_fd = syscall(__NR_perf_event_open, &attr, 0 /* pid */,
163                          -1 /* cpu */, -1 /* group_fd */, 0 /* flags */);
164         if (pmu_fd == -1) {
165                 if (errno == ENOENT) {
166                         printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n",
167                                __func__);
168                         test__skip();
169                         return;
170                 }
171                 /* Let the test fail with a more informative message */
172         } else {
173                 close(pmu_fd);
174         }
175 
176         test_send_signal_common(&attr, signal_thread, "perf_hw_event");
177 }
178 
179 void test_send_signal(void)
180 {
181         if (test__start_subtest("send_signal_tracepoint"))
182                 test_send_signal_tracepoint(false);
183         if (test__start_subtest("send_signal_perf"))
184                 test_send_signal_perf(false);
185         if (test__start_subtest("send_signal_nmi"))
186                 test_send_signal_nmi(false);
187         if (test__start_subtest("send_signal_tracepoint_thread"))
188                 test_send_signal_tracepoint(true);
189         if (test__start_subtest("send_signal_perf_thread"))
190                 test_send_signal_perf(true);
191         if (test__start_subtest("send_signal_nmi_thread"))
192                 test_send_signal_nmi(true);
193 }
194 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp