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.

Merge tag 'trace-user-events-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing user-event updates from Steven Rostedt:

- Minor update to the user_events interface

The ABI of creating a user event states that the fields are separated
by semicolons, and spaces should be ignored.

But the parsing expected at least one space to be there (which was
incorrect). Fix the reading of the string to handle fields separated
by semicolons but no space between them.

This does extend the API sightly as now "field;field" will now be
parsed and not cause an error. But it should not cause any regressions
as no logic should expect it to fail.

Note, that the logic that parses the event fields to create the
trace_event works with no spaces after the semi-colon. It is
the logic that tests against existing events that is inconsistent.
This causes registering an event without using spaces to succeed
if it doesn't exist, but makes the same call that tries to register
to the same event, but doesn't use spaces, fail.

* tag 'trace-user-events-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
selftests/user_events: Add non-spacing separator check
tracing/user_events: Fix non-spaced field matching

+83 -1
+75 -1
kernel/trace/trace_events_user.c
··· 1990 1990 } 1991 1991 1992 1992 /* 1993 + * Counts how many ';' without a trailing space are in the args. 1994 + */ 1995 + static int count_semis_no_space(char *args) 1996 + { 1997 + int count = 0; 1998 + 1999 + while ((args = strchr(args, ';'))) { 2000 + args++; 2001 + 2002 + if (!isspace(*args)) 2003 + count++; 2004 + } 2005 + 2006 + return count; 2007 + } 2008 + 2009 + /* 2010 + * Copies the arguments while ensuring all ';' have a trailing space. 2011 + */ 2012 + static char *insert_space_after_semis(char *args, int count) 2013 + { 2014 + char *fixed, *pos; 2015 + int len; 2016 + 2017 + len = strlen(args) + count; 2018 + fixed = kmalloc(len + 1, GFP_KERNEL); 2019 + 2020 + if (!fixed) 2021 + return NULL; 2022 + 2023 + pos = fixed; 2024 + 2025 + /* Insert a space after ';' if there is no trailing space. */ 2026 + while (*args) { 2027 + *pos = *args++; 2028 + 2029 + if (*pos++ == ';' && !isspace(*args)) 2030 + *pos++ = ' '; 2031 + } 2032 + 2033 + *pos = '\0'; 2034 + 2035 + return fixed; 2036 + } 2037 + 2038 + static char **user_event_argv_split(char *args, int *argc) 2039 + { 2040 + char **split; 2041 + char *fixed; 2042 + int count; 2043 + 2044 + /* Count how many ';' without a trailing space */ 2045 + count = count_semis_no_space(args); 2046 + 2047 + /* No fixup is required */ 2048 + if (!count) 2049 + return argv_split(GFP_KERNEL, args, argc); 2050 + 2051 + /* We must fixup 'field;field' to 'field; field' */ 2052 + fixed = insert_space_after_semis(args, count); 2053 + 2054 + if (!fixed) 2055 + return NULL; 2056 + 2057 + /* We do a normal split afterwards */ 2058 + split = argv_split(GFP_KERNEL, fixed, argc); 2059 + 2060 + /* We can free since argv_split makes a copy */ 2061 + kfree(fixed); 2062 + 2063 + return split; 2064 + } 2065 + 2066 + /* 1993 2067 * Parses the event name, arguments and flags then registers if successful. 1994 2068 * The name buffer lifetime is owned by this method for success cases only. 1995 2069 * Upon success the returned user_event has its ref count increased by 1. ··· 2086 2012 return -EPERM; 2087 2013 2088 2014 if (args) { 2089 - argv = argv_split(GFP_KERNEL, args, &argc); 2015 + argv = user_event_argv_split(args, &argc); 2090 2016 2091 2017 if (!argv) 2092 2018 return -ENOMEM;
+8
tools/testing/selftests/user_events/ftrace_test.c
··· 261 261 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 262 262 ASSERT_EQ(0, reg.write_index); 263 263 264 + /* Register without separator spacing should still match */ 265 + reg.enable_bit = 29; 266 + reg.name_args = (__u64)"__test_event u32 field1;u32 field2"; 267 + ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, &reg)); 268 + ASSERT_EQ(0, reg.write_index); 269 + 264 270 /* Multiple registers to same name but different args should fail */ 265 271 reg.enable_bit = 29; 266 272 reg.name_args = (__u64)"__test_event u32 field1;"; ··· 293 287 /* Unregister */ 294 288 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); 295 289 unreg.disable_bit = 30; 290 + ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); 291 + unreg.disable_bit = 29; 296 292 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); 297 293 298 294 /* Delete should have been auto-done after close and unregister */