Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tracing/user_events: Update self-tests to write ABI

ABI has been changed to remote writes, update existing test cases to use
this new ABI to ensure existing functionality continues to work.

Link: https://lkml.kernel.org/r/20230328235219.203-7-beaub@linux.microsoft.com

Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Beau Belgrave and committed by
Steven Rostedt (Google)
0d309f04 dcb8177c

+96 -89
+83 -69
tools/testing/selftests/user_events/ftrace_test.c
··· 12 12 #include <fcntl.h> 13 13 #include <sys/ioctl.h> 14 14 #include <sys/stat.h> 15 + #include <sys/uio.h> 15 16 #include <unistd.h> 16 17 17 18 #include "../kselftest_harness.h" ··· 22 21 const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable"; 23 22 const char *trace_file = "/sys/kernel/tracing/trace"; 24 23 const char *fmt_file = "/sys/kernel/tracing/events/user_events/__test_event/format"; 25 - 26 - static inline int status_check(char *status_page, int status_bit) 27 - { 28 - return status_page[status_bit >> 3] & (1 << (status_bit & 7)); 29 - } 30 24 31 25 static int trace_bytes(void) 32 26 { ··· 102 106 return -1; 103 107 } 104 108 105 - static int clear(void) 109 + static int clear(int *check) 106 110 { 111 + struct user_unreg unreg = {0}; 112 + 113 + unreg.size = sizeof(unreg); 114 + unreg.disable_bit = 31; 115 + unreg.disable_addr = (__u64)check; 116 + 107 117 int fd = open(data_file, O_RDWR); 108 118 109 119 if (fd == -1) 110 120 return -1; 121 + 122 + if (ioctl(fd, DIAG_IOCSUNREG, &unreg) == -1) 123 + if (errno != ENOENT) 124 + return -1; 111 125 112 126 if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1) 113 127 if (errno != ENOENT) ··· 128 122 return 0; 129 123 } 130 124 131 - static int check_print_fmt(const char *event, const char *expected) 125 + static int check_print_fmt(const char *event, const char *expected, int *check) 132 126 { 133 127 struct user_reg reg = {0}; 134 128 char print_fmt[256]; ··· 136 130 int fd; 137 131 138 132 /* Ensure cleared */ 139 - ret = clear(); 133 + ret = clear(check); 140 134 141 135 if (ret != 0) 142 136 return ret; ··· 148 142 149 143 reg.size = sizeof(reg); 150 144 reg.name_args = (__u64)event; 145 + reg.enable_bit = 31; 146 + reg.enable_addr = (__u64)check; 147 + reg.enable_size = sizeof(*check); 151 148 152 149 /* Register should work */ 153 150 ret = ioctl(fd, DIAG_IOCSREG, &reg); 154 151 155 152 close(fd); 156 153 157 - if (ret != 0) 154 + if (ret != 0) { 155 + printf("Reg failed in fmt\n"); 158 156 return ret; 157 + } 159 158 160 159 /* Ensure correct print_fmt */ 161 160 ret = get_print_fmt(print_fmt, sizeof(print_fmt)); ··· 175 164 int status_fd; 176 165 int data_fd; 177 166 int enable_fd; 167 + int check; 178 168 }; 179 169 180 170 FIXTURE_SETUP(user) { ··· 197 185 close(self->enable_fd); 198 186 } 199 187 200 - ASSERT_EQ(0, clear()); 188 + if (clear(&self->check) != 0) 189 + printf("WARNING: Clear didn't work!\n"); 201 190 } 202 191 203 192 TEST_F(user, register_events) { 204 193 struct user_reg reg = {0}; 205 - int page_size = sysconf(_SC_PAGESIZE); 206 - char *status_page; 194 + struct user_unreg unreg = {0}; 207 195 208 196 reg.size = sizeof(reg); 209 197 reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; 198 + reg.enable_bit = 31; 199 + reg.enable_addr = (__u64)&self->check; 200 + reg.enable_size = sizeof(self->check); 210 201 211 - status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED, 212 - self->status_fd, 0); 202 + unreg.size = sizeof(unreg); 203 + unreg.disable_bit = 31; 204 + unreg.disable_addr = (__u64)&self->check; 213 205 214 206 /* Register should work */ 215 207 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 216 208 ASSERT_EQ(0, reg.write_index); 217 - ASSERT_NE(0, reg.status_bit); 218 209 219 210 /* Multiple registers should result in same index */ 220 211 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 221 212 ASSERT_EQ(0, reg.write_index); 222 - ASSERT_NE(0, reg.status_bit); 223 213 224 214 /* Ensure disabled */ 225 215 self->enable_fd = open(enable_file, O_RDWR); 226 216 ASSERT_NE(-1, self->enable_fd); 227 217 ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0"))) 228 218 229 - /* MMAP should work and be zero'd */ 230 - ASSERT_NE(MAP_FAILED, status_page); 231 - ASSERT_NE(NULL, status_page); 232 - ASSERT_EQ(0, status_check(status_page, reg.status_bit)); 233 - 234 219 /* Enable event and ensure bits updated in status */ 235 220 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 236 - ASSERT_NE(0, status_check(status_page, reg.status_bit)); 221 + ASSERT_EQ(1 << reg.enable_bit, self->check); 237 222 238 223 /* Disable event and ensure bits updated in status */ 239 224 ASSERT_NE(-1, write(self->enable_fd, "0", sizeof("0"))) 240 - ASSERT_EQ(0, status_check(status_page, reg.status_bit)); 225 + ASSERT_EQ(0, self->check); 241 226 242 227 /* File still open should return -EBUSY for delete */ 243 228 ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event")); 244 229 ASSERT_EQ(EBUSY, errno); 245 230 246 - /* Delete should work only after close */ 231 + /* Unregister */ 232 + ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); 233 + 234 + /* Delete should work only after close and unregister */ 247 235 close(self->data_fd); 248 236 self->data_fd = open(data_file, O_RDWR); 249 237 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event")); 250 - 251 - /* Unmap should work */ 252 - ASSERT_EQ(0, munmap(status_page, page_size)); 253 238 } 254 239 255 240 TEST_F(user, write_events) { ··· 254 245 struct iovec io[3]; 255 246 __u32 field1, field2; 256 247 int before = 0, after = 0; 257 - int page_size = sysconf(_SC_PAGESIZE); 258 - char *status_page; 259 248 260 249 reg.size = sizeof(reg); 261 250 reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; 251 + reg.enable_bit = 31; 252 + reg.enable_addr = (__u64)&self->check; 253 + reg.enable_size = sizeof(self->check); 262 254 263 255 field1 = 1; 264 256 field2 = 2; ··· 271 261 io[2].iov_base = &field2; 272 262 io[2].iov_len = sizeof(field2); 273 263 274 - status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED, 275 - self->status_fd, 0); 276 - 277 264 /* Register should work */ 278 265 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 279 266 ASSERT_EQ(0, reg.write_index); 280 - ASSERT_NE(0, reg.status_bit); 281 - 282 - /* MMAP should work and be zero'd */ 283 - ASSERT_NE(MAP_FAILED, status_page); 284 - ASSERT_NE(NULL, status_page); 285 - ASSERT_EQ(0, status_check(status_page, reg.status_bit)); 267 + ASSERT_EQ(0, self->check); 286 268 287 269 /* Write should fail on invalid slot with ENOENT */ 288 270 io[0].iov_base = &field2; ··· 289 287 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 290 288 291 289 /* Event should now be enabled */ 292 - ASSERT_NE(0, status_check(status_page, reg.status_bit)); 290 + ASSERT_NE(1 << reg.enable_bit, self->check); 293 291 294 292 /* Write should make it out to ftrace buffers */ 295 293 before = trace_bytes(); ··· 306 304 307 305 reg.size = sizeof(reg); 308 306 reg.name_args = (__u64)"__test_event u64 anon"; 307 + reg.enable_bit = 31; 308 + reg.enable_addr = (__u64)&self->check; 309 + reg.enable_size = sizeof(self->check); 309 310 310 311 anon = mmap(NULL, l, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 311 312 ASSERT_NE(MAP_FAILED, anon); ··· 321 316 /* Register should work */ 322 317 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 323 318 ASSERT_EQ(0, reg.write_index); 324 - ASSERT_NE(0, reg.status_bit); 325 319 326 320 /* Write should work normally */ 327 321 ASSERT_NE(-1, writev(self->data_fd, (const struct iovec *)io, 2)); ··· 337 333 int loc, bytes; 338 334 char data[8]; 339 335 int before = 0, after = 0; 340 - int page_size = sysconf(_SC_PAGESIZE); 341 - char *status_page; 342 - 343 - status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED, 344 - self->status_fd, 0); 345 336 346 337 reg.size = sizeof(reg); 347 338 reg.name_args = (__u64)"__test_event __rel_loc char[] data"; 339 + reg.enable_bit = 31; 340 + reg.enable_addr = (__u64)&self->check; 341 + reg.enable_size = sizeof(self->check); 348 342 349 343 /* Register should work */ 350 344 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 351 345 ASSERT_EQ(0, reg.write_index); 352 - ASSERT_NE(0, reg.status_bit); 353 - 354 - /* MMAP should work and be zero'd */ 355 - ASSERT_NE(MAP_FAILED, status_page); 356 - ASSERT_NE(NULL, status_page); 357 - ASSERT_EQ(0, status_check(status_page, reg.status_bit)); 346 + ASSERT_EQ(0, self->check); 358 347 359 348 io[0].iov_base = &reg.write_index; 360 349 io[0].iov_len = sizeof(reg.write_index); ··· 366 369 ASSERT_NE(-1, write(self->enable_fd, "1", sizeof("1"))) 367 370 368 371 /* Event should now be enabled */ 369 - ASSERT_NE(0, status_check(status_page, reg.status_bit)); 372 + ASSERT_EQ(1 << reg.enable_bit, self->check); 370 373 371 374 /* Full in-bounds write should work */ 372 375 before = trace_bytes(); ··· 406 409 int ret; 407 410 408 411 ret = check_print_fmt("__test_event __rel_loc char[] data", 409 - "print fmt: \"data=%s\", __get_rel_str(data)"); 412 + "print fmt: \"data=%s\", __get_rel_str(data)", 413 + &self->check); 410 414 ASSERT_EQ(0, ret); 411 415 412 416 ret = check_print_fmt("__test_event __data_loc char[] data", 413 - "print fmt: \"data=%s\", __get_str(data)"); 417 + "print fmt: \"data=%s\", __get_str(data)", 418 + &self->check); 414 419 ASSERT_EQ(0, ret); 415 420 416 421 ret = check_print_fmt("__test_event s64 data", 417 - "print fmt: \"data=%lld\", REC->data"); 422 + "print fmt: \"data=%lld\", REC->data", 423 + &self->check); 418 424 ASSERT_EQ(0, ret); 419 425 420 426 ret = check_print_fmt("__test_event u64 data", 421 - "print fmt: \"data=%llu\", REC->data"); 427 + "print fmt: \"data=%llu\", REC->data", 428 + &self->check); 422 429 ASSERT_EQ(0, ret); 423 430 424 431 ret = check_print_fmt("__test_event s32 data", 425 - "print fmt: \"data=%d\", REC->data"); 432 + "print fmt: \"data=%d\", REC->data", 433 + &self->check); 426 434 ASSERT_EQ(0, ret); 427 435 428 436 ret = check_print_fmt("__test_event u32 data", 429 - "print fmt: \"data=%u\", REC->data"); 437 + "print fmt: \"data=%u\", REC->data", 438 + &self->check); 430 439 ASSERT_EQ(0, ret); 431 440 432 441 ret = check_print_fmt("__test_event int data", 433 - "print fmt: \"data=%d\", REC->data"); 442 + "print fmt: \"data=%d\", REC->data", 443 + &self->check); 434 444 ASSERT_EQ(0, ret); 435 445 436 446 ret = check_print_fmt("__test_event unsigned int data", 437 - "print fmt: \"data=%u\", REC->data"); 447 + "print fmt: \"data=%u\", REC->data", 448 + &self->check); 438 449 ASSERT_EQ(0, ret); 439 450 440 451 ret = check_print_fmt("__test_event s16 data", 441 - "print fmt: \"data=%d\", REC->data"); 452 + "print fmt: \"data=%d\", REC->data", 453 + &self->check); 442 454 ASSERT_EQ(0, ret); 443 455 444 456 ret = check_print_fmt("__test_event u16 data", 445 - "print fmt: \"data=%u\", REC->data"); 457 + "print fmt: \"data=%u\", REC->data", 458 + &self->check); 446 459 ASSERT_EQ(0, ret); 447 460 448 461 ret = check_print_fmt("__test_event short data", 449 - "print fmt: \"data=%d\", REC->data"); 462 + "print fmt: \"data=%d\", REC->data", 463 + &self->check); 450 464 ASSERT_EQ(0, ret); 451 465 452 466 ret = check_print_fmt("__test_event unsigned short data", 453 - "print fmt: \"data=%u\", REC->data"); 467 + "print fmt: \"data=%u\", REC->data", 468 + &self->check); 454 469 ASSERT_EQ(0, ret); 455 470 456 471 ret = check_print_fmt("__test_event s8 data", 457 - "print fmt: \"data=%d\", REC->data"); 472 + "print fmt: \"data=%d\", REC->data", 473 + &self->check); 458 474 ASSERT_EQ(0, ret); 459 475 460 476 ret = check_print_fmt("__test_event u8 data", 461 - "print fmt: \"data=%u\", REC->data"); 477 + "print fmt: \"data=%u\", REC->data", 478 + &self->check); 462 479 ASSERT_EQ(0, ret); 463 480 464 481 ret = check_print_fmt("__test_event char data", 465 - "print fmt: \"data=%d\", REC->data"); 482 + "print fmt: \"data=%d\", REC->data", 483 + &self->check); 466 484 ASSERT_EQ(0, ret); 467 485 468 486 ret = check_print_fmt("__test_event unsigned char data", 469 - "print fmt: \"data=%u\", REC->data"); 487 + "print fmt: \"data=%u\", REC->data", 488 + &self->check); 470 489 ASSERT_EQ(0, ret); 471 490 472 491 ret = check_print_fmt("__test_event char[4] data", 473 - "print fmt: \"data=%s\", REC->data"); 492 + "print fmt: \"data=%s\", REC->data", 493 + &self->check); 474 494 ASSERT_EQ(0, ret); 475 495 } 476 496
+13 -20
tools/testing/selftests/user_events/perf_test.c
··· 19 19 #include "../kselftest_harness.h" 20 20 21 21 const char *data_file = "/sys/kernel/tracing/user_events_data"; 22 - const char *status_file = "/sys/kernel/tracing/user_events_status"; 23 22 const char *id_file = "/sys/kernel/tracing/events/user_events/__test_event/id"; 24 23 const char *fmt_file = "/sys/kernel/tracing/events/user_events/__test_event/format"; 25 24 ··· 32 33 int cpu, int group_fd, unsigned long flags) 33 34 { 34 35 return syscall(__NR_perf_event_open, pe, pid, cpu, group_fd, flags); 35 - } 36 - 37 - static inline int status_check(char *status_page, int status_bit) 38 - { 39 - return status_page[status_bit >> 3] & (1 << (status_bit & 7)); 40 36 } 41 37 42 38 static int get_id(void) ··· 82 88 } 83 89 84 90 FIXTURE(user) { 85 - int status_fd; 86 91 int data_fd; 92 + int check; 87 93 }; 88 94 89 95 FIXTURE_SETUP(user) { 90 - self->status_fd = open(status_file, O_RDONLY); 91 - ASSERT_NE(-1, self->status_fd); 92 - 93 96 self->data_fd = open(data_file, O_RDWR); 94 97 ASSERT_NE(-1, self->data_fd); 95 98 } 96 99 97 100 FIXTURE_TEARDOWN(user) { 98 - close(self->status_fd); 99 101 close(self->data_fd); 100 102 } 101 103 102 104 TEST_F(user, perf_write) { 103 105 struct perf_event_attr pe = {0}; 104 106 struct user_reg reg = {0}; 105 - int page_size = sysconf(_SC_PAGESIZE); 106 - char *status_page; 107 107 struct event event; 108 108 struct perf_event_mmap_page *perf_page; 109 + int page_size = sysconf(_SC_PAGESIZE); 109 110 int id, fd, offset; 110 111 __u32 *val; 111 112 112 113 reg.size = sizeof(reg); 113 114 reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; 114 - 115 - status_page = mmap(NULL, page_size, PROT_READ, MAP_SHARED, 116 - self->status_fd, 0); 117 - ASSERT_NE(MAP_FAILED, status_page); 115 + reg.enable_bit = 31; 116 + reg.enable_addr = (__u64)&self->check; 117 + reg.enable_size = sizeof(self->check); 118 118 119 119 /* Register should work */ 120 120 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 121 121 ASSERT_EQ(0, reg.write_index); 122 - ASSERT_NE(0, reg.status_bit); 123 - ASSERT_EQ(0, status_check(status_page, reg.status_bit)); 122 + ASSERT_EQ(0, self->check); 124 123 125 124 /* Id should be there */ 126 125 id = get_id(); ··· 136 149 ASSERT_NE(MAP_FAILED, perf_page); 137 150 138 151 /* Status should be updated */ 139 - ASSERT_NE(0, status_check(status_page, reg.status_bit)); 152 + ASSERT_EQ(1 << reg.enable_bit, self->check); 140 153 141 154 event.index = reg.write_index; 142 155 event.field1 = 0xc001; ··· 152 165 /* Ensure correct */ 153 166 ASSERT_EQ(event.field1, *val++); 154 167 ASSERT_EQ(event.field2, *val++); 168 + 169 + munmap(perf_page, page_size * 2); 170 + close(fd); 171 + 172 + /* Status should be updated */ 173 + ASSERT_EQ(0, self->check); 155 174 } 156 175 157 176 int main(int argc, char **argv)