* [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly
@ 2019-10-21 9:47 Qu Wenruo
2019-10-21 13:56 ` Steven Rostedt
0 siblings, 1 reply; 6+ messages in thread
From: Qu Wenruo @ 2019-10-21 9:47 UTC (permalink / raw)
To: linux-btrfs, linux-kernel, linux-trace-devel
[BUG]
For btrfs related events, there is a field for fsid, but perf never
parse it correctly.
# perf trace -e btrfs:qgroup_meta_convert xfs_io -f -c "pwrite 0 4k" \
/mnt/btrfs/file1
0.000 xfs_io/77915 btrfs:qgroup_meta_reserve:(nil)U: refroot=5(FS_TREE) type=0x0 diff=2
^^^^^^ Not a correct UUID
...
[CAUSE]
The pretty_print() function doesn't handle the %pU format correctly.
In fact it doesn't handle %pU as uuid at all.
[FIX]
Add a new function, print_uuid_arg(), to handle %pU correctly.
Now perf trace can at least print fsid correctly:
0.000 xfs_io/79619 btrfs:qgroup_meta_reserve:23ad1511-dd83-47d4-a79c-e96625a15a6e refroot=5(FS_TREE) type=0x0 diff=2
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
Changelog:
v2:
- Use more comment explaining the finetunings we skipped for %pU*
- Extra check for the field before reading the data
- Use more elegant way to output uuid string
v3:
- Use a even more elegant way to output uuid string
---
tools/lib/traceevent/event-parse.c | 51 ++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index d948475585ce..a71f4a86b6ca 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <stdint.h>
#include <limits.h>
+#include <linux/uuid.h>
#include <linux/time64.h>
#include <netinet/in.h>
@@ -4508,6 +4509,40 @@ get_bprint_format(void *data, int size __maybe_unused,
return format;
}
+static void print_uuid_arg(struct trace_seq *s, void *data, int size,
+ struct tep_event *event, struct tep_print_arg *arg)
+{
+ unsigned char *buf;
+ int i;
+
+ if (arg->type != TEP_PRINT_FIELD) {
+ trace_seq_printf(s, "ARG TYPE NOT FIELID but %d", arg->type);
+ return;
+ }
+
+ if (!arg->field.field) {
+ arg->field.field = tep_find_any_field(event, arg->field.name);
+ if (!arg->field.field) {
+ do_warning("%s: field %s not found",
+ __func__, arg->field.name);
+ return;
+ }
+ }
+ if (arg->field.field->size < 16) {
+ trace_seq_printf(s, "INVALID UUID: size have %u expect 16",
+ arg->field.field->size);
+ return;
+ }
+ buf = data + arg->field.field->offset;
+
+ for (i = 0; i < 8; i++) {
+ trace_seq_printf(s, "%02x", buf[2 * i]);
+ trace_seq_printf(s, "%02x", buf[2 * i + 1]);
+ if (1 <= i && i <= 4)
+ trace_seq_putc(s, '-');
+ }
+}
+
static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
struct tep_event *event, struct tep_print_arg *arg)
{
@@ -5074,6 +5109,22 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_e
arg = arg->next;
break;
}
+ } else if (*ptr == 'U') {
+ /*
+ * %pU has several finetunings variants
+ * like %pUb and %pUL.
+ * Here we ignore them, default to
+ * byte-order no endian, lower case
+ * letters.
+ */
+ if (isalpha(ptr[1]))
+ ptr += 2;
+ else
+ ptr++;
+
+ print_uuid_arg(s, data, size, event, arg);
+ arg = arg->next;
+ break;
}
/* fall through */
--
2.23.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly
2019-10-21 9:47 [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly Qu Wenruo
@ 2019-10-21 13:56 ` Steven Rostedt
2019-10-21 14:03 ` Qu Wenruo
0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2019-10-21 13:56 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, linux-kernel, linux-trace-devel
On Mon, 21 Oct 2019 17:47:30 +0800
Qu Wenruo <wqu@suse.com> wrote:
> +static void print_uuid_arg(struct trace_seq *s, void *data, int size,
> + struct tep_event *event, struct tep_print_arg *arg)
> +{
> + unsigned char *buf;
> + int i;
> +
> + if (arg->type != TEP_PRINT_FIELD) {
> + trace_seq_printf(s, "ARG TYPE NOT FIELID but %d", arg->type);
> + return;
> + }
> +
> + if (!arg->field.field) {
> + arg->field.field = tep_find_any_field(event, arg->field.name);
> + if (!arg->field.field) {
> + do_warning("%s: field %s not found",
> + __func__, arg->field.name);
> + return;
> + }
> + }
> + if (arg->field.field->size < 16) {
> + trace_seq_printf(s, "INVALID UUID: size have %u expect 16",
> + arg->field.field->size);
> + return;
> + }
> + buf = data + arg->field.field->offset;
> +
> + for (i = 0; i < 8; i++) {
> + trace_seq_printf(s, "%02x", buf[2 * i]);
> + trace_seq_printf(s, "%02x", buf[2 * i + 1]);
> + if (1 <= i && i <= 4)
I'm fine with this patch except for one nit. The above is hard to read
(in my opinion), and I absolutely hate the "constant" compare to
"variable" notation. Please change the above to:
if (i >= 1 && i <= 4)
Thanks,
-- Steve
> + trace_seq_putc(s, '-');
> + }
> +}
> +
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly
2019-10-21 13:56 ` Steven Rostedt
@ 2019-10-21 14:03 ` Qu Wenruo
2019-10-21 14:24 ` Steven Rostedt
0 siblings, 1 reply; 6+ messages in thread
From: Qu Wenruo @ 2019-10-21 14:03 UTC (permalink / raw)
To: Steven Rostedt, Qu Wenruo; +Cc: linux-btrfs, linux-kernel, linux-trace-devel
[-- Attachment #1.1: Type: text/plain, Size: 1691 bytes --]
On 2019/10/21 下午9:56, Steven Rostedt wrote:
> On Mon, 21 Oct 2019 17:47:30 +0800
> Qu Wenruo <wqu@suse.com> wrote:
>
>> +static void print_uuid_arg(struct trace_seq *s, void *data, int size,
>> + struct tep_event *event, struct tep_print_arg *arg)
>> +{
>> + unsigned char *buf;
>> + int i;
>> +
>> + if (arg->type != TEP_PRINT_FIELD) {
>> + trace_seq_printf(s, "ARG TYPE NOT FIELID but %d", arg->type);
>> + return;
>> + }
>> +
>> + if (!arg->field.field) {
>> + arg->field.field = tep_find_any_field(event, arg->field.name);
>> + if (!arg->field.field) {
>> + do_warning("%s: field %s not found",
>> + __func__, arg->field.name);
>> + return;
>> + }
>> + }
>> + if (arg->field.field->size < 16) {
>> + trace_seq_printf(s, "INVALID UUID: size have %u expect 16",
>> + arg->field.field->size);
>> + return;
>> + }
>> + buf = data + arg->field.field->offset;
>> +
>> + for (i = 0; i < 8; i++) {
>> + trace_seq_printf(s, "%02x", buf[2 * i]);
>> + trace_seq_printf(s, "%02x", buf[2 * i + 1]);
>> + if (1 <= i && i <= 4)
>
> I'm fine with this patch except for one nit. The above is hard to read
> (in my opinion), and I absolutely hate the "constant" compare to
> "variable" notation. Please change the above to:
>
> if (i >= 1 && i <= 4)
Isn't this ( 1 <= i && i <= 4 ) easier to find out the lower and upper
boundary? only two numbers, both at the end of the expression.
I feel that ( i >= 1 && i <= 4 ) easier to write, but takes me extra
half second to read, thus I changed to the current one.
Thanks,
Qu
>
> Thanks,
>
> -- Steve
>
>> + trace_seq_putc(s, '-');
>> + }
>> +}
>> +
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly
2019-10-21 14:03 ` Qu Wenruo
@ 2019-10-21 14:24 ` Steven Rostedt
2019-10-21 14:30 ` Qu Wenruo
0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2019-10-21 14:24 UTC (permalink / raw)
To: Qu Wenruo; +Cc: Qu Wenruo, linux-btrfs, linux-kernel, linux-trace-devel
On Mon, 21 Oct 2019 22:03:21 +0800
Qu Wenruo <quwenruo.btrfs@gmx.com> wrote:
> On 2019/10/21 下午9:56, Steven Rostedt wrote:
> > On Mon, 21 Oct 2019 17:47:30 +0800
> > Qu Wenruo <wqu@suse.com> wrote:
> >
> >> +static void print_uuid_arg(struct trace_seq *s, void *data, int size,
> >> + struct tep_event *event, struct tep_print_arg *arg)
> >> +{
> >> + unsigned char *buf;
> >> + int i;
> >> +
> >> + if (arg->type != TEP_PRINT_FIELD) {
> >> + trace_seq_printf(s, "ARG TYPE NOT FIELID but %d", arg->type);
> >> + return;
> >> + }
> >> +
> >> + if (!arg->field.field) {
> >> + arg->field.field = tep_find_any_field(event, arg->field.name);
> >> + if (!arg->field.field) {
> >> + do_warning("%s: field %s not found",
> >> + __func__, arg->field.name);
> >> + return;
> >> + }
> >> + }
> >> + if (arg->field.field->size < 16) {
> >> + trace_seq_printf(s, "INVALID UUID: size have %u expect 16",
> >> + arg->field.field->size);
> >> + return;
> >> + }
> >> + buf = data + arg->field.field->offset;
> >> +
> >> + for (i = 0; i < 8; i++) {
> >> + trace_seq_printf(s, "%02x", buf[2 * i]);
> >> + trace_seq_printf(s, "%02x", buf[2 * i + 1]);
> >> + if (1 <= i && i <= 4)
> >
> > I'm fine with this patch except for one nit. The above is hard to read
> > (in my opinion), and I absolutely hate the "constant" compare to
> > "variable" notation. Please change the above to:
> >
> > if (i >= 1 && i <= 4)
>
> Isn't this ( 1 <= i && i <= 4 ) easier to find out the lower and upper
> boundary? only two numbers, both at the end of the expression.
I don't read it like that.
>
> I feel that ( i >= 1 && i <= 4 ) easier to write, but takes me extra
> half second to read, thus I changed to the current one.
How do you read it in English?
"If one is less than or equal to i and i is less than or equal to
four."
Or
"If i is greater than or equal to one and i is less than or equal to
four."
?
I read it the second way, and I believe most English speakers read it
that way too.
It took me a minute or two to understand the original method, because
my mind likes to take a variable and keep it on the same side of the
comparison, and the variable should always be first.
-- Steve
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly
2019-10-21 14:24 ` Steven Rostedt
@ 2019-10-21 14:30 ` Qu Wenruo
2019-10-21 15:34 ` Steven Rostedt
0 siblings, 1 reply; 6+ messages in thread
From: Qu Wenruo @ 2019-10-21 14:30 UTC (permalink / raw)
To: Steven Rostedt; +Cc: Qu Wenruo, linux-btrfs, linux-kernel, linux-trace-devel
[-- Attachment #1.1: Type: text/plain, Size: 2556 bytes --]
On 2019/10/21 下午10:24, Steven Rostedt wrote:
> On Mon, 21 Oct 2019 22:03:21 +0800
> Qu Wenruo <quwenruo.btrfs@gmx.com> wrote:
>
>> On 2019/10/21 下午9:56, Steven Rostedt wrote:
>>> On Mon, 21 Oct 2019 17:47:30 +0800
>>> Qu Wenruo <wqu@suse.com> wrote:
>>>
>>>> +static void print_uuid_arg(struct trace_seq *s, void *data, int size,
>>>> + struct tep_event *event, struct tep_print_arg *arg)
>>>> +{
>>>> + unsigned char *buf;
>>>> + int i;
>>>> +
>>>> + if (arg->type != TEP_PRINT_FIELD) {
>>>> + trace_seq_printf(s, "ARG TYPE NOT FIELID but %d", arg->type);
>>>> + return;
>>>> + }
>>>> +
>>>> + if (!arg->field.field) {
>>>> + arg->field.field = tep_find_any_field(event, arg->field.name);
>>>> + if (!arg->field.field) {
>>>> + do_warning("%s: field %s not found",
>>>> + __func__, arg->field.name);
>>>> + return;
>>>> + }
>>>> + }
>>>> + if (arg->field.field->size < 16) {
>>>> + trace_seq_printf(s, "INVALID UUID: size have %u expect 16",
>>>> + arg->field.field->size);
>>>> + return;
>>>> + }
>>>> + buf = data + arg->field.field->offset;
>>>> +
>>>> + for (i = 0; i < 8; i++) {
>>>> + trace_seq_printf(s, "%02x", buf[2 * i]);
>>>> + trace_seq_printf(s, "%02x", buf[2 * i + 1]);
>>>> + if (1 <= i && i <= 4)
>>>
>>> I'm fine with this patch except for one nit. The above is hard to read
>>> (in my opinion), and I absolutely hate the "constant" compare to
>>> "variable" notation. Please change the above to:
>>>
>>> if (i >= 1 && i <= 4)
>>
>> Isn't this ( 1 <= i && i <= 4 ) easier to find out the lower and upper
>> boundary? only two numbers, both at the end of the expression.
>
> I don't read it like that.
>
>>
>> I feel that ( i >= 1 && i <= 4 ) easier to write, but takes me extra
>> half second to read, thus I changed to the current one.
>
> How do you read it in English?
How about mathematics interval?
i in [1, 4].
It looks way easier and simpler no matter what language you speak.
Thanks,
Qu
>
> "If one is less than or equal to i and i is less than or equal to
> four."
>
> Or
>
> "If i is greater than or equal to one and i is less than or equal to
> four."
>
> ?
>
> I read it the second way, and I believe most English speakers read it
> that way too.
>
> It took me a minute or two to understand the original method, because
> my mind likes to take a variable and keep it on the same side of the
> comparison, and the variable should always be first.
>
> -- Steve
>
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly
2019-10-21 14:30 ` Qu Wenruo
@ 2019-10-21 15:34 ` Steven Rostedt
0 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2019-10-21 15:34 UTC (permalink / raw)
To: Qu Wenruo; +Cc: Qu Wenruo, linux-btrfs, linux-kernel, linux-trace-devel
On Mon, 21 Oct 2019 22:30:37 +0800
Qu Wenruo <quwenruo.btrfs@gmx.com> wrote:
> > How do you read it in English?
>
> How about mathematics interval?
>
> i in [1, 4].
>
> It looks way easier and simpler no matter what language you speak.
But C doesn't accept that syntax ;-)
-- Steve
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-10-21 15:34 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-21 9:47 [PATCH v3] tools/lib/traceevent, perf tools: Handle %pU format correctly Qu Wenruo
2019-10-21 13:56 ` Steven Rostedt
2019-10-21 14:03 ` Qu Wenruo
2019-10-21 14:24 ` Steven Rostedt
2019-10-21 14:30 ` Qu Wenruo
2019-10-21 15:34 ` Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).