1 // SPDX-License-Identifier: GPL-2.0
3 * User Events Dyn Events Test Program
5 * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com>
9 #include <linux/user_events.h>
13 #include <sys/ioctl.h>
17 #include "../kselftest_harness.h"
18 #include "user_events_selftests.h"
20 const char *dyn_file
= "/sys/kernel/tracing/dynamic_events";
21 const char *abi_file
= "/sys/kernel/tracing/user_events_data";
22 const char *enable_file
= "/sys/kernel/tracing/events/user_events/__test_event/enable";
24 static int event_delete(void)
26 int fd
= open(abi_file
, O_RDWR
);
32 ret
= ioctl(fd
, DIAG_IOCSDEL
, "__test_event");
39 static bool wait_for_delete(void)
43 for (i
= 0; i
< 1000; ++i
) {
44 int fd
= open(enable_file
, O_RDONLY
);
56 static int reg_event(int fd
, int *check
, int bit
, const char *value
)
58 struct user_reg reg
= {0};
60 reg
.size
= sizeof(reg
);
61 reg
.name_args
= (__u64
)value
;
63 reg
.enable_addr
= (__u64
)check
;
64 reg
.enable_size
= sizeof(*check
);
66 if (ioctl(fd
, DIAG_IOCSREG
, ®
) == -1)
72 static int unreg_event(int fd
, int *check
, int bit
)
74 struct user_unreg unreg
= {0};
76 unreg
.size
= sizeof(unreg
);
77 unreg
.disable_bit
= bit
;
78 unreg
.disable_addr
= (__u64
)check
;
80 return ioctl(fd
, DIAG_IOCSUNREG
, &unreg
);
83 static int parse_dyn(const char *value
)
85 int fd
= open(dyn_file
, O_RDWR
| O_APPEND
);
86 int len
= strlen(value
);
92 ret
= write(fd
, value
, len
);
107 static int parse_abi(int *check
, const char *value
)
109 int fd
= open(abi_file
, O_RDWR
);
115 /* Until we have persist flags via dynamic events, use the base name */
116 if (value
[0] != 'u' || value
[1] != ':') {
121 ret
= reg_event(fd
, check
, 31, value
+ 2);
124 if (unreg_event(fd
, check
, 31) == -1)
125 printf("WARN: Couldn't unreg event\n");
133 static int parse(int *check
, const char *value
)
135 int abi_ret
= parse_abi(check
, value
);
136 int dyn_ret
= parse_dyn(value
);
138 /* Ensure both ABI and DYN parse the same way */
139 if (dyn_ret
!= abi_ret
)
145 static int check_match(int *check
, const char *first
, const char *second
, bool *match
)
147 int fd
= open(abi_file
, O_RDWR
);
153 if (reg_event(fd
, check
, 31, first
) == -1)
156 if (reg_event(fd
, check
, 30, second
) == -1) {
157 if (errno
== EADDRINUSE
) {
158 /* Name is in use, with different fields */
169 unreg_event(fd
, check
, 31);
170 unreg_event(fd
, check
, 30);
179 #define TEST_MATCH(x, y) \
182 ASSERT_NE(-1, check_match(&self->check, x, y, &match)); \
183 ASSERT_EQ(true, match); \
186 #define TEST_NMATCH(x, y) \
189 ASSERT_NE(-1, check_match(&self->check, x, y, &match)); \
190 ASSERT_EQ(false, match); \
193 #define TEST_PARSE(x) ASSERT_NE(-1, parse(&self->check, x))
195 #define TEST_NPARSE(x) ASSERT_EQ(-1, parse(&self->check, x))
202 FIXTURE_SETUP(user
) {
203 USER_EVENT_FIXTURE_SETUP(return, self
->umount
);
206 FIXTURE_TEARDOWN(user
) {
207 USER_EVENT_FIXTURE_TEARDOWN(self
->umount
);
212 TEST_F(user
, basic_types
) {
213 /* All should work */
214 TEST_PARSE("u:__test_event u64 a");
215 TEST_PARSE("u:__test_event u32 a");
216 TEST_PARSE("u:__test_event u16 a");
217 TEST_PARSE("u:__test_event u8 a");
218 TEST_PARSE("u:__test_event char a");
219 TEST_PARSE("u:__test_event unsigned char a");
220 TEST_PARSE("u:__test_event int a");
221 TEST_PARSE("u:__test_event unsigned int a");
222 TEST_PARSE("u:__test_event short a");
223 TEST_PARSE("u:__test_event unsigned short a");
224 TEST_PARSE("u:__test_event char[20] a");
225 TEST_PARSE("u:__test_event unsigned char[20] a");
226 TEST_PARSE("u:__test_event char[0x14] a");
227 TEST_PARSE("u:__test_event unsigned char[0x14] a");
228 /* Bad size format should fail */
229 TEST_NPARSE("u:__test_event char[aa] a");
230 /* Large size should fail */
231 TEST_NPARSE("u:__test_event char[9999] a");
232 /* Long size string should fail */
233 TEST_NPARSE("u:__test_event char[0x0000000000001] a");
236 TEST_F(user
, loc_types
) {
237 /* All should work */
238 TEST_PARSE("u:__test_event __data_loc char[] a");
239 TEST_PARSE("u:__test_event __data_loc unsigned char[] a");
240 TEST_PARSE("u:__test_event __rel_loc char[] a");
241 TEST_PARSE("u:__test_event __rel_loc unsigned char[] a");
244 TEST_F(user
, size_types
) {
246 TEST_PARSE("u:__test_event struct custom a 20");
247 /* Size not specified on struct should fail */
248 TEST_NPARSE("u:__test_event struct custom a");
249 /* Size specified on non-struct should fail */
250 TEST_NPARSE("u:__test_event char a 20");
253 TEST_F(user
, matching
) {
254 /* Single name matches */
255 TEST_MATCH("__test_event u32 a",
256 "__test_event u32 a");
258 /* Multiple names match */
259 TEST_MATCH("__test_event u32 a; u32 b",
260 "__test_event u32 a; u32 b");
262 /* Multiple names match with dangling ; */
263 TEST_MATCH("__test_event u32 a; u32 b",
264 "__test_event u32 a; u32 b;");
266 /* Single name doesn't match */
267 TEST_NMATCH("__test_event u32 a",
268 "__test_event u32 b");
270 /* Multiple names don't match */
271 TEST_NMATCH("__test_event u32 a; u32 b",
272 "__test_event u32 b; u32 a");
274 /* Types don't match */
275 TEST_NMATCH("__test_event u64 a; u64 b",
276 "__test_event u32 a; u32 b");
278 /* Struct name and size matches */
279 TEST_MATCH("__test_event struct my_struct a 20",
280 "__test_event struct my_struct a 20");
282 /* Struct name don't match */
283 TEST_NMATCH("__test_event struct my_struct a 20",
284 "__test_event struct my_struct b 20");
286 /* Struct size don't match */
287 TEST_NMATCH("__test_event struct my_struct a 20",
288 "__test_event struct my_struct a 21");
291 int main(int argc
, char **argv
)
293 return test_harness_run(argc
, argv
);