diff options
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 | } |