selftests/user_events: Ensure auto cleanup works as expected
authorBeau Belgrave <beaub@linux.microsoft.com>
Wed, 14 Jun 2023 16:33:34 +0000 (09:33 -0700)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Wed, 14 Jun 2023 17:43:27 +0000 (13:43 -0400)
User events now auto cleanup upon the last reference put. Update
ftrace_test to ensure this works as expected. Ensure EBUSY delays
while event is being deleted do not cause transient failures by
waiting and re-attempting.

Link: https://lkml.kernel.org/r/20230614163336.5797-5-beaub@linux.microsoft.com
Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
tools/testing/selftests/user_events/ftrace_test.c

index abfb495..eb6904d 100644 (file)
@@ -102,30 +102,56 @@ err:
        return -1;
 }
 
+static bool wait_for_delete(void)
+{
+       int i;
+
+       for (i = 0; i < 1000; ++i) {
+               int fd = open(enable_file, O_RDONLY);
+
+               if (fd == -1)
+                       return true;
+
+               close(fd);
+               usleep(1000);
+       }
+
+       return false;
+}
+
 static int clear(int *check)
 {
        struct user_unreg unreg = {0};
+       int fd;
 
        unreg.size = sizeof(unreg);
        unreg.disable_bit = 31;
        unreg.disable_addr = (__u64)check;
 
-       int fd = open(data_file, O_RDWR);
+       fd = open(data_file, O_RDWR);
 
        if (fd == -1)
                return -1;
 
        if (ioctl(fd, DIAG_IOCSUNREG, &unreg) == -1)
                if (errno != ENOENT)
-                       return -1;
-
-       if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1)
-               if (errno != ENOENT)
-                       return -1;
+                       goto fail;
+
+       if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1) {
+               if (errno == EBUSY) {
+                       if (!wait_for_delete())
+                               goto fail;
+               } else if (errno != ENOENT)
+                       goto fail;
+       }
 
        close(fd);
 
        return 0;
+fail:
+       close(fd);
+
+       return -1;
 }
 
 static int check_print_fmt(const char *event, const char *expected, int *check)
@@ -155,9 +181,8 @@ static int check_print_fmt(const char *event, const char *expected, int *check)
        /* Register should work */
        ret = ioctl(fd, DIAG_IOCSREG, &reg);
 
-       close(fd);
-
        if (ret != 0) {
+               close(fd);
                printf("Reg failed in fmt\n");
                return ret;
        }
@@ -165,6 +190,8 @@ static int check_print_fmt(const char *event, const char *expected, int *check)
        /* Ensure correct print_fmt */
        ret = get_print_fmt(print_fmt, sizeof(print_fmt));
 
+       close(fd);
+
        if (ret != 0)
                return ret;
 
@@ -256,10 +283,10 @@ TEST_F(user, register_events) {
        unreg.disable_bit = 30;
        ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg));
 
-       /* Delete should work only after close and unregister */
+       /* Delete should have been auto-done after close and unregister */
        close(self->data_fd);
-       self->data_fd = open(data_file, O_RDWR);
-       ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSDEL, "__test_event"));
+
+       ASSERT_EQ(true, wait_for_delete());
 }
 
 TEST_F(user, write_events) {