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

selftests/user_events: Test persist flag cases

Now that we have exposed USER_EVENT_REG_PERSIST events can persist both
via the ABI and in the /sys/kernel/tracing/dynamic_events file.

Ensure both the ABI and DYN cases work by calling both during the parse
tests. Add new flags test that ensures only USER_EVENT_REG_PERSIST is
honored and any other flag is invalid.

Link: https://lkml.kernel.org/r/20230912180704.1284-3-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)
cf74c59c 5dbd04ed

+107 -2
+54 -1
tools/testing/selftests/user_events/abi_test.c
··· 24 24 const char *data_file = "/sys/kernel/tracing/user_events_data"; 25 25 const char *enable_file = "/sys/kernel/tracing/events/user_events/__abi_event/enable"; 26 26 27 + static bool event_exists(void) 28 + { 29 + int fd = open(enable_file, O_RDWR); 30 + 31 + if (fd < 0) 32 + return false; 33 + 34 + close(fd); 35 + 36 + return true; 37 + } 38 + 27 39 static int change_event(bool enable) 28 40 { 29 41 int fd = open(enable_file, O_RDWR); ··· 59 47 return ret; 60 48 } 61 49 62 - static int reg_enable(long *enable, int size, int bit) 50 + static int event_delete(void) 51 + { 52 + int fd = open(data_file, O_RDWR); 53 + int ret; 54 + 55 + if (fd < 0) 56 + return -1; 57 + 58 + ret = ioctl(fd, DIAG_IOCSDEL, "__abi_event"); 59 + 60 + close(fd); 61 + 62 + return ret; 63 + } 64 + 65 + static int reg_enable_flags(long *enable, int size, int bit, int flags) 63 66 { 64 67 struct user_reg reg = {0}; 65 68 int fd = open(data_file, O_RDWR); ··· 85 58 86 59 reg.size = sizeof(reg); 87 60 reg.name_args = (__u64)"__abi_event"; 61 + reg.flags = flags; 88 62 reg.enable_bit = bit; 89 63 reg.enable_addr = (__u64)enable; 90 64 reg.enable_size = size; ··· 95 67 close(fd); 96 68 97 69 return ret; 70 + } 71 + 72 + static int reg_enable(long *enable, int size, int bit) 73 + { 74 + return reg_enable_flags(enable, size, bit, 0); 98 75 } 99 76 100 77 static int reg_disable(long *enable, int bit) ··· 157 124 ASSERT_EQ(0, change_event(true)); 158 125 ASSERT_EQ(0, self->check); 159 126 ASSERT_EQ(0, change_event(false)); 127 + } 128 + 129 + TEST_F(user, flags) { 130 + /* USER_EVENT_REG_PERSIST is allowed */ 131 + ASSERT_EQ(0, reg_enable_flags(&self->check, sizeof(int), 0, 132 + USER_EVENT_REG_PERSIST)); 133 + ASSERT_EQ(0, reg_disable(&self->check, 0)); 134 + 135 + /* Ensure it exists after close and disable */ 136 + ASSERT_TRUE(event_exists()); 137 + 138 + /* Ensure we can delete it */ 139 + ASSERT_EQ(0, event_delete()); 140 + 141 + /* USER_EVENT_REG_MAX or above is not allowed */ 142 + ASSERT_EQ(-1, reg_enable_flags(&self->check, sizeof(int), 0, 143 + USER_EVENT_REG_MAX)); 144 + 145 + /* Ensure it does not exist after invalid flags */ 146 + ASSERT_FALSE(event_exists()); 160 147 } 161 148 162 149 TEST_F(user, bit_sizes) {
+53 -1
tools/testing/selftests/user_events/dyn_test.c
··· 17 17 #include "../kselftest_harness.h" 18 18 #include "user_events_selftests.h" 19 19 20 + const char *dyn_file = "/sys/kernel/tracing/dynamic_events"; 20 21 const char *abi_file = "/sys/kernel/tracing/user_events_data"; 21 22 const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable"; 23 + 24 + static int event_delete(void) 25 + { 26 + int fd = open(abi_file, O_RDWR); 27 + int ret; 28 + 29 + if (fd < 0) 30 + return -1; 31 + 32 + ret = ioctl(fd, DIAG_IOCSDEL, "__test_event"); 33 + 34 + close(fd); 35 + 36 + return ret; 37 + } 22 38 23 39 static bool wait_for_delete(void) 24 40 { ··· 80 64 return ioctl(fd, DIAG_IOCSUNREG, &unreg); 81 65 } 82 66 83 - static int parse(int *check, const char *value) 67 + static int parse_dyn(const char *value) 68 + { 69 + int fd = open(dyn_file, O_RDWR | O_APPEND); 70 + int len = strlen(value); 71 + int ret; 72 + 73 + if (fd == -1) 74 + return -1; 75 + 76 + ret = write(fd, value, len); 77 + 78 + if (ret == len) 79 + ret = 0; 80 + else 81 + ret = -1; 82 + 83 + close(fd); 84 + 85 + if (ret == 0) 86 + event_delete(); 87 + 88 + return ret; 89 + } 90 + 91 + static int parse_abi(int *check, const char *value) 84 92 { 85 93 int fd = open(abi_file, O_RDWR); 86 94 int ret; ··· 128 88 close(fd); 129 89 130 90 return ret; 91 + } 92 + 93 + static int parse(int *check, const char *value) 94 + { 95 + int abi_ret = parse_abi(check, value); 96 + int dyn_ret = parse_dyn(value); 97 + 98 + /* Ensure both ABI and DYN parse the same way */ 99 + if (dyn_ret != abi_ret) 100 + return -1; 101 + 102 + return dyn_ret; 131 103 } 132 104 133 105 static int check_match(int *check, const char *first, const char *second, bool *match)