diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-03-02 13:53:59 -0500 |
---|---|---|
committer | Steven Rostedt <srostedt@redhat.com> | 2009-03-02 14:27:27 -0500 |
commit | 981d081ec8b958b7d962ee40d433581a55d40fc5 (patch) | |
tree | 366aa5da7dc98cc2354002946e6f19ec60c02301 /kernel/trace/trace_events.c | |
parent | f9520750c4c9924c14325cd951efae5fae58104c (diff) |
tracing: add format file to describe event struct fields
This patch adds the "format" file to the trace point event directory.
This is based off of work by Tom Zanussi, in which a file is exported
to be tread from user land such that a user space app may read the
binary record stored in the ring buffer.
# cat /debug/tracing/events/sched/sched_switch/format
field:pid_t prev_pid; offset:12; size:4;
field:int prev_prio; offset:16; size:4;
field special:char next_comm[TASK_COMM_LEN]; offset:20; size:16;
field:pid_t next_pid; offset:36; size:4;
field:int next_prio; offset:40; size:4;
Idea-from: Tom Zanussi <tzanussi@gmail.com>
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r-- | kernel/trace/trace_events.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 26069fa6b3b..d57a772981c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> | 4 | * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> |
5 | * | 5 | * |
6 | * - Added format output of fields of the trace point. | ||
7 | * This was based off of work by Tom Zanussi <tzanussi@gmail.com>. | ||
8 | * | ||
6 | */ | 9 | */ |
7 | 10 | ||
8 | #include <linux/debugfs.h> | 11 | #include <linux/debugfs.h> |
@@ -444,6 +447,42 @@ event_available_types_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
444 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 447 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
445 | } | 448 | } |
446 | 449 | ||
450 | static ssize_t | ||
451 | event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | ||
452 | loff_t *ppos) | ||
453 | { | ||
454 | struct ftrace_event_call *call = filp->private_data; | ||
455 | struct trace_seq *s; | ||
456 | char *buf; | ||
457 | int r; | ||
458 | |||
459 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
460 | if (!s) | ||
461 | return -ENOMEM; | ||
462 | |||
463 | trace_seq_init(s); | ||
464 | |||
465 | if (*ppos) | ||
466 | return 0; | ||
467 | |||
468 | r = call->show_format(s); | ||
469 | if (!r) { | ||
470 | /* | ||
471 | * ug! The format output is bigger than a PAGE!! | ||
472 | */ | ||
473 | buf = "FORMAT TOO BIG\n"; | ||
474 | r = simple_read_from_buffer(ubuf, cnt, ppos, | ||
475 | buf, strlen(buf)); | ||
476 | goto out; | ||
477 | } | ||
478 | |||
479 | r = simple_read_from_buffer(ubuf, cnt, ppos, | ||
480 | s->buffer, s->len); | ||
481 | out: | ||
482 | kfree(s); | ||
483 | return r; | ||
484 | } | ||
485 | |||
447 | static const struct seq_operations show_event_seq_ops = { | 486 | static const struct seq_operations show_event_seq_ops = { |
448 | .start = t_start, | 487 | .start = t_start, |
449 | .next = t_next, | 488 | .next = t_next, |
@@ -490,6 +529,11 @@ static const struct file_operations ftrace_available_types_fops = { | |||
490 | .read = event_available_types_read, | 529 | .read = event_available_types_read, |
491 | }; | 530 | }; |
492 | 531 | ||
532 | static const struct file_operations ftrace_event_format_fops = { | ||
533 | .open = tracing_open_generic, | ||
534 | .read = event_format_read, | ||
535 | }; | ||
536 | |||
493 | static struct dentry *event_trace_events_dir(void) | 537 | static struct dentry *event_trace_events_dir(void) |
494 | { | 538 | { |
495 | static struct dentry *d_tracer; | 539 | static struct dentry *d_tracer; |
@@ -602,7 +646,17 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events) | |||
602 | &ftrace_available_types_fops); | 646 | &ftrace_available_types_fops); |
603 | if (!entry) | 647 | if (!entry) |
604 | pr_warning("Could not create debugfs " | 648 | pr_warning("Could not create debugfs " |
605 | "'%s/type' available_types\n", call->name); | 649 | "'%s/available_types' entry\n", call->name); |
650 | |||
651 | /* A trace may not want to export its format */ | ||
652 | if (!call->show_format) | ||
653 | return 0; | ||
654 | |||
655 | entry = debugfs_create_file("format", 0444, call->dir, call, | ||
656 | &ftrace_event_format_fops); | ||
657 | if (!entry) | ||
658 | pr_warning("Could not create debugfs " | ||
659 | "'%s/format' entry\n", call->name); | ||
606 | 660 | ||
607 | return 0; | 661 | return 0; |
608 | } | 662 | } |