* [PATCH 1/3] Clean up unused argsz
@ 2025-09-13 15:56 eugene.loh
2025-09-13 15:56 ` [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful eugene.loh
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: eugene.loh @ 2025-09-13 15:56 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_provider_tp.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c
index 4531a88a8..33821f2c7 100644
--- a/libdtrace/dt_provider_tp.c
+++ b/libdtrace/dt_provider_tp.c
@@ -141,7 +141,6 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
char *buf = NULL;
size_t bufsz;
int argc;
- size_t argsz = 0;
dt_argdesc_t *argv = NULL;
tpp->id = 0;
@@ -153,8 +152,7 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
/*
* Pass 1:
- * Determine the event id and the number of arguments (along with the
- * total size of all type strings together).
+ * Determine the event id and the number of arguments.
*/
argc = -skip;
while (getline(&buf, &bufsz, f) >= 0) {
@@ -170,12 +168,6 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
/* We found a field: description - see if we should skip it. */
if (argc++ < 0)
continue;
-
- /*
- * We over-estimate the space needed (pass 2 will strip off the
- * identifier name).
- */
- argsz += strlen(p) + 1;
}
free(buf);
buf = NULL;
--
2.47.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful 2025-09-13 15:56 [PATCH 1/3] Clean up unused argsz eugene.loh @ 2025-09-13 15:56 ` eugene.loh 2025-09-14 13:17 ` Nick Alcock 2025-09-13 15:56 ` [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields eugene.loh 2025-09-14 13:11 ` [DTrace-devel] [PATCH 1/3] Clean up unused argsz Nick Alcock 2 siblings, 1 reply; 8+ messages in thread From: eugene.loh @ 2025-09-13 15:56 UTC (permalink / raw) To: dtrace, dtrace-devel From: Eugene Loh <eugene.loh@oracle.com> Signed-off-by: Eugene Loh <eugene.loh@oracle.com> --- libdtrace/dt_provider_tp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c index 33821f2c7..a6f978e3f 100644 --- a/libdtrace/dt_provider_tp.c +++ b/libdtrace/dt_provider_tp.c @@ -208,12 +208,13 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, p = buf; if (sscanf(buf, " field:%[^;]", p) <= 0) continue; - sscanf(p, "__data_loc %[^;]", p); /* We found a field: description - see if we should skip it. */ if (argc < 0) goto skip; + sscanf(p, "__data_loc %[^;]", p); + /* * If the last character is not ']', the last token must be the * identifier name. Get rid of it. -- 2.47.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful 2025-09-13 15:56 ` [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful eugene.loh @ 2025-09-14 13:17 ` Nick Alcock 2025-09-15 4:50 ` Eugene Loh 0 siblings, 1 reply; 8+ messages in thread From: Nick Alcock @ 2025-09-14 13:17 UTC (permalink / raw) To: eugene.loh; +Cc: dtrace, dtrace-devel On 13 Sep 2025, eugene loh uttered the following: > From: Eugene Loh <eugene.loh@oracle.com> > > Signed-off-by: Eugene Loh <eugene.loh@oracle.com> Reviewed-by: Nick Alcock <nick.alcock@oracle.com> with the tiny caveat below. > --- > libdtrace/dt_provider_tp.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c > index 33821f2c7..a6f978e3f 100644 > --- a/libdtrace/dt_provider_tp.c > +++ b/libdtrace/dt_provider_tp.c > @@ -208,12 +208,13 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, > p = buf; > if (sscanf(buf, " field:%[^;]", p) <= 0) > continue; > - sscanf(p, "__data_loc %[^;]", p); > > /* We found a field: description - see if we should skip it. */ > if (argc < 0) > goto skip; > > + sscanf(p, "__data_loc %[^;]", p); > + ... why not defer the sscanf above it too? The manipulation of argc at this point looks like this: argc = -skip; (in getline loop) /* We found a field: description - see if we should skip it. */ if (argc < 0) goto skip; (at loop end) skip: argc++; } So if argc is < 0, it's going to *stay* like that until a given number of getlines have happened. Doing more work than just skipping and getlining is pointless. (This affects the next patch as much as this one. More generally, it might be clearer to move skipping to a separate getline loop entirely, above this one that also does all the other work.) -- NULL && (void) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful 2025-09-14 13:17 ` Nick Alcock @ 2025-09-15 4:50 ` Eugene Loh 0 siblings, 0 replies; 8+ messages in thread From: Eugene Loh @ 2025-09-15 4:50 UTC (permalink / raw) To: Nick Alcock; +Cc: dtrace, dtrace-devel On 9/14/25 09:17, Nick Alcock wrote: > On 13 Sep 2025, eugene loh uttered the following: > >> From: Eugene Loh <eugene.loh@oracle.com> >> >> Signed-off-by: Eugene Loh <eugene.loh@oracle.com> > Reviewed-by: Nick Alcock <nick.alcock@oracle.com> Great, thanks. > with the tiny caveat below. > >> --- >> libdtrace/dt_provider_tp.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c >> index 33821f2c7..a6f978e3f 100644 >> --- a/libdtrace/dt_provider_tp.c >> +++ b/libdtrace/dt_provider_tp.c >> @@ -208,12 +208,13 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, >> p = buf; >> if (sscanf(buf, " field:%[^;]", p) <= 0) >> continue; >> - sscanf(p, "__data_loc %[^;]", p); >> >> /* We found a field: description - see if we should skip it. */ >> if (argc < 0) >> goto skip; >> >> + sscanf(p, "__data_loc %[^;]", p); >> + > ... why not defer the sscanf above it too? Because it's watching for "field:" lines. We're not counting lines; we're counting lines with "field:" in them. > The manipulation of argc at > this point looks like this: > > argc = -skip; > > (in getline loop) > > /* We found a field: description - see if we should skip it. */ > if (argc < 0) > goto skip; > (at loop end) > skip: > argc++; > } > > > So if argc is < 0, it's going to *stay* like that until a given number > of getlines have happened. Doing more work than just skipping and > getlining is pointless. Again, we're counting lines that have "field:" in them. Now, I suppose we could count lines, period, whether they have "field:" in them or not (e.g., the ID: line), but I'm okay with forgoing that change until some future patch. I get that this "__data_loc" change is no more relevant than what you propose. But, if folks are okay with it, I wouldn't mind just pushing ahead with the patch as it is. But, yeah, you make a reasonable suggestion. Thanks. > (This affects the next patch as much as this > one. More generally, it might be clearer to move skipping to a separate > getline loop entirely, above this one that also does all the other work.) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields 2025-09-13 15:56 [PATCH 1/3] Clean up unused argsz eugene.loh 2025-09-13 15:56 ` [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful eugene.loh @ 2025-09-13 15:56 ` eugene.loh 2025-09-14 13:26 ` [DTrace-devel] " Nick Alcock 2025-09-14 13:11 ` [DTrace-devel] [PATCH 1/3] Clean up unused argsz Nick Alcock 2 siblings, 1 reply; 8+ messages in thread From: eugene.loh @ 2025-09-13 15:56 UTC (permalink / raw) To: dtrace, dtrace-devel From: Eugene Loh <eugene.loh@oracle.com> In dt_tp_event_info(), we parse tracepoint format files -- e.g., /sys/kernel/debug/tracing/events/*/*/format. Specifically, we are interested in the argument descriptions found in the file, but we are interested in skipping over "common fields." The mechanism we used for this purpose was, in dt_provider_tp.c, to hardwire the number of fields to skip to SKIP_FIELDS_COUNT=4, assuming the common fields would always be type, flags, pid, and preempt_count. This is hardly a robust mechanism. For example, consider https://kernel.googlesource.com/pub/scm/linux/kernel/git/rt/ linux-rt-devel/+/refs/tags/v5.9.1-rt20-patches/patches/ preempt-lazy-support.patch which introduces a preempt_lazy_count common field (on top of others). Recent dtrace testing on RHCK 5.14 indicates widespread test failures due to this problem. Implement a more robust mechanism. Specifically, instead of skipping a hardwired (SKIP_FIELDS_COUNT=4) number of common fields, look for "common_" names. E.g., in kernel/trace/trace_events.c in trace_define_common_fields(), we see the macro __common_field() is used to define common fields, and the names are prepended with "common_". Signed-off-by: Eugene Loh <eugene.loh@oracle.com> --- libdtrace/dt_provider_tp.c | 83 ++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c index a6f978e3f..13f4528fc 100644 --- a/libdtrace/dt_provider_tp.c +++ b/libdtrace/dt_provider_tp.c @@ -17,13 +17,6 @@ #include "dt_probe.h" #include "dt_impl.h" -/* - * All tracing events (tracepoints) include a number of fields that we need to - * skip in the tracepoint format description. These fields are: common_type, - * common_flags, common_preempt_coint, and common_pid. - */ -#define SKIP_FIELDS_COUNT 4 - /* * Tracepoint-specific probe data. This is allocated for every tracepoint * based probe. Since 0 is not a valid tracepoint event id, and given that BTF @@ -129,10 +122,10 @@ dt_tp_attach_raw(dtrace_hdl_t *dtp, tp_probe_t *tpp, const char *name, * the identifier isn't as easy because it may be suffixed by one or more * array dimension specifiers (and those are part of the type). * - * All events include a number of fields that we are not interested in and that - * need to be skipped (SKIP_FIELDS_COUNT). Callers of this function can - * specify an additional number of fields to skip (using the 'skip' parameter) - * before we get to the actual arguments. + * All events include a number of common fields that we are not interested + * in and that need to be skipped. Callers of this function can specify an + * additional number of fields to skip (using the 'skip' parameter) before + * we get to the actual arguments. */ int dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, @@ -140,19 +133,16 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, { char *buf = NULL; size_t bufsz; - int argc; + int argc, common = 1; dt_argdesc_t *argv = NULL; tpp->id = 0; - /* - * Let skip be the total number of fields to skip. - */ - skip += SKIP_FIELDS_COUNT; - /* * Pass 1: * Determine the event id and the number of arguments. + * Skip over how ever many arguments the caller asks us to skip. + * We will skip initial "common fields" as well. */ argc = -skip; while (getline(&buf, &bufsz, f) >= 0) { @@ -160,14 +150,63 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, if (sscanf(buf, "ID: %u\n", &tpp->id) == 1) continue; - if (sscanf(buf, " field:%[^;]", p) <= 0) continue; - sscanf(p, "__data_loc %[^;]", p); - /* We found a field: description - see if we should skip it. */ - if (argc++ < 0) - continue; + /* + * If we have only seen common fields to date, keep + * looking for a non-common field. + */ + if (common == 1) { + char *s = p + strlen(p) - 1; + + /* + * Strip off any [] array size specifications at the end. + */ + while (*s == ']') { + /* From ']' hunt back to '['. They are not nested. */ + while (s > p && *(--s) != '[') ; + + /* Then remove any spaces. */ + while (s > p && *(--s) == ' ') ; + } + *(++s) = '\0'; + + /* + * Go to the beginning of the identifier. + */ + p = strrchr(p, ' '); + if (p == NULL) + return -EINVAL; + p++; + + /* + * Check if it is a common field. + * + * In kernel source file kernel/trace/trace_events.c + * in trace_define_common_fields(), the macro + * __common_field() is used to define common fields, + * prepending names with "common_". + */ + if (strncmp(p, "common_", 7) == 0) { + /* + * For Pass 2, we will not bother checking + * for "common" fields; we will just pretend + * the caller asked us to skip more arguments. + */ + skip++; + + continue; + } + + /* + * No more need to check for common fields. + */ + common = 0; + } + + /* We found a non-common "field:" description. */ + argc++; } free(buf); buf = NULL; -- 2.47.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [DTrace-devel] [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields 2025-09-13 15:56 ` [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields eugene.loh @ 2025-09-14 13:26 ` Nick Alcock 2025-09-15 4:56 ` Eugene Loh 0 siblings, 1 reply; 8+ messages in thread From: Nick Alcock @ 2025-09-14 13:26 UTC (permalink / raw) To: eugene.loh; +Cc: dtrace, dtrace-devel On 13 Sep 2025, eugene loh stated: > Implement a more robust mechanism. > > Specifically, instead of skipping a hardwired (SKIP_FIELDS_COUNT=4) > number of common fields, look for "common_" names. E.g., in > kernel/trace/trace_events.c in trace_define_common_fields(), we > see the macro __common_field() is used to define common fields, > and the names are prepended with "common_". (If this turns out not to work, maybe we can hunt for the blank line that always seems to follow common_* fields?) > while (getline(&buf, &bufsz, f) >= 0) { This is much clearer than it was before! Reviewed-by: Nick Alcock <nick.alcock@oracle.com> > @@ -160,14 +150,63 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, > > if (sscanf(buf, "ID: %u\n", &tpp->id) == 1) > continue; > - > if (sscanf(buf, " field:%[^;]", p) <= 0) > continue; > - sscanf(p, "__data_loc %[^;]", p); > > - /* We found a field: description - see if we should skip it. */ > - if (argc++ < 0) > - continue; > + /* > + * If we have only seen common fields to date, keep > + * looking for a non-common field. > + */ > + if (common == 1) { ... ok, I take back the thing I said in the previous mail about moving things to a separate loop: the ID/field scan is necessary anyway, given the first two lines: ID: 94 format: field:unsigned short common_type; offset:0; size:2; signed:0; Given the overall format of e.g. name: sys_enter_iopl ID: 94 format: field:unsigned short common_type; offset:0; size:2; signed:0; field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1; signed:0; field:int common_pid; offset:4; size:4; signed:1; field:int __syscall_nr; offset:8; size:4; signed:1; an alternative approach might be to exploit the format, and always skip all lines that do not start with a tab, and/or simply all lines until the first entirely blank line? Maybe? (Looking at the kernel source, the common fields always seem to be followed by a blank one.) But this approach will work for now, though it appears to be pure coincidence that all common fields start with common_. We definitely have workable alternative approaches if this stops working :) Hmm... + /* + * Strip off any [] array size specifications at the end. + */ + while (*s == ']') { + /* From ']' hunt back to '['. They are not nested. */ + while (s > p && *(--s) != '[') ; + + /* Then remove any spaces. */ + while (s > p && *(--s) == ' ') ; + } + *(++s) = '\0'; Why is this necessary? We never look at the end of the identifier in the common_ search, only the start... ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [DTrace-devel] [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields 2025-09-14 13:26 ` [DTrace-devel] " Nick Alcock @ 2025-09-15 4:56 ` Eugene Loh 0 siblings, 0 replies; 8+ messages in thread From: Eugene Loh @ 2025-09-15 4:56 UTC (permalink / raw) To: Nick Alcock; +Cc: dtrace, dtrace-devel On 9/14/25 09:26, Nick Alcock wrote: > On 13 Sep 2025, eugene loh stated: >> Implement a more robust mechanism. >> >> Specifically, instead of skipping a hardwired (SKIP_FIELDS_COUNT=4) >> number of common fields, look for "common_" names. E.g., in >> kernel/trace/trace_events.c in trace_define_common_fields(), we >> see the macro __common_field() is used to define common fields, >> and the names are prepended with "common_". > (If this turns out not to work, maybe we can hunt for the blank line > that always seems to follow common_* fields?) > >> while (getline(&buf, &bufsz, f) >= 0) { > This is much clearer than it was before! > > Reviewed-by: Nick Alcock <nick.alcock@oracle.com> > >> @@ -160,14 +150,63 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp, >> >> if (sscanf(buf, "ID: %u\n", &tpp->id) == 1) >> continue; >> - >> if (sscanf(buf, " field:%[^;]", p) <= 0) >> continue; >> - sscanf(p, "__data_loc %[^;]", p); >> >> - /* We found a field: description - see if we should skip it. */ >> - if (argc++ < 0) >> - continue; >> + /* >> + * If we have only seen common fields to date, keep >> + * looking for a non-common field. >> + */ >> + if (common == 1) { > ... ok, I take back the thing I said in the previous mail about moving > things to a separate loop: the ID/field scan is necessary anyway, given > the first two lines: > > ID: 94 > format: > field:unsigned short common_type; offset:0; size:2; signed:0; > > Given the overall format of e.g. > > name: sys_enter_iopl > ID: 94 > format: > field:unsigned short common_type; offset:0; size:2; signed:0; > field:unsigned char common_flags; offset:2; size:1; signed:0; > field:unsigned char common_preempt_count; offset:3; size:1; signed:0; > field:int common_pid; offset:4; size:4; signed:1; > > field:int __syscall_nr; offset:8; size:4; signed:1; > > an alternative approach might be to exploit the format, and always skip > all lines that do not start with a tab, and/or simply all lines until > the first entirely blank line? Maybe? (Looking at the kernel source, the > common fields always seem to be followed by a blank one.) > > But this approach will work for now, though it appears to be pure > coincidence that all common fields start with common_. Coincidence? As the patch notes, commons fields are inserted via a macro that prepends "common_". Not a coincidence! > We definitely > have workable alternative approaches if this stops working :) > > Hmm... > > + /* > + * Strip off any [] array size specifications at the end. > + */ > + while (*s == ']') { > + /* From ']' hunt back to '['. They are not nested. */ > + while (s > p && *(--s) != '[') ; > + > + /* Then remove any spaces. */ > + while (s > p && *(--s) == ' ') ; > + } > + *(++s) = '\0'; > > Why is this necessary? We never look at the end of the identifier in the > common_ search, only the start... I used to look simply for "common_". Kris was concerned that a type might have this string, messing things up. So, we want to make sure, specifically, that it's the identifier that starts with "common_". So, how do we find the start of the identifier? It's the last token... *after* any trailing [] are stripped off. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [DTrace-devel] [PATCH 1/3] Clean up unused argsz 2025-09-13 15:56 [PATCH 1/3] Clean up unused argsz eugene.loh 2025-09-13 15:56 ` [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful eugene.loh 2025-09-13 15:56 ` [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields eugene.loh @ 2025-09-14 13:11 ` Nick Alcock 2 siblings, 0 replies; 8+ messages in thread From: Nick Alcock @ 2025-09-14 13:11 UTC (permalink / raw) To: eugene.loh; +Cc: dtrace-devel, dtrace On 13 Sep 2025, eugene loh stated: > From: Eugene Loh <eugene.loh@oracle.com> > > Signed-off-by: Eugene Loh <eugene.loh@oracle.com> Reviewed-by: Nick Alcock <nick.alcock@oracle.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-09-15 4:56 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-13 15:56 [PATCH 1/3] Clean up unused argsz eugene.loh 2025-09-13 15:56 ` [PATCH 2/3] Defer stripping out "__data_loc" until we know that is useful eugene.loh 2025-09-14 13:17 ` Nick Alcock 2025-09-15 4:50 ` Eugene Loh 2025-09-13 15:56 ` [PATCH v2 3/3] Add more robust mechanism to skip tracepoint common fields eugene.loh 2025-09-14 13:26 ` [DTrace-devel] " Nick Alcock 2025-09-15 4:56 ` Eugene Loh 2025-09-14 13:11 ` [DTrace-devel] [PATCH 1/3] Clean up unused argsz Nick Alcock
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox