diff options
-rw-r--r-- | Documentation/trace/kprobetrace.txt | 8 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 43 |
2 files changed, 51 insertions, 0 deletions
diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index 5e59e854e71b..3de751747164 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt | |||
@@ -70,6 +70,14 @@ filter: | |||
70 | names and field names for describing filters. | 70 | names and field names for describing filters. |
71 | 71 | ||
72 | 72 | ||
73 | Event Profiling | ||
74 | --------------- | ||
75 | You can check the total number of probe hits and probe miss-hits via | ||
76 | /sys/kernel/debug/tracing/kprobe_profile. | ||
77 | The first column is event name, the second is the number of probe hits, | ||
78 | the third is the number of probe miss-hits. | ||
79 | |||
80 | |||
73 | Usage examples | 81 | Usage examples |
74 | -------------- | 82 | -------------- |
75 | To add a probe as a new event, write a new definition to kprobe_events | 83 | To add a probe as a new event, write a new definition to kprobe_events |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 9c067bf47d50..ce68197767de 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -184,6 +184,7 @@ struct trace_probe { | |||
184 | struct kprobe kp; | 184 | struct kprobe kp; |
185 | struct kretprobe rp; | 185 | struct kretprobe rp; |
186 | }; | 186 | }; |
187 | unsigned long nhit; | ||
187 | const char *symbol; /* symbol name */ | 188 | const char *symbol; /* symbol name */ |
188 | struct ftrace_event_call call; | 189 | struct ftrace_event_call call; |
189 | struct trace_event event; | 190 | struct trace_event event; |
@@ -781,6 +782,37 @@ static const struct file_operations kprobe_events_ops = { | |||
781 | .write = probes_write, | 782 | .write = probes_write, |
782 | }; | 783 | }; |
783 | 784 | ||
785 | /* Probes profiling interfaces */ | ||
786 | static int probes_profile_seq_show(struct seq_file *m, void *v) | ||
787 | { | ||
788 | struct trace_probe *tp = v; | ||
789 | |||
790 | seq_printf(m, " %-44s %15lu %15lu\n", tp->call.name, tp->nhit, | ||
791 | probe_is_return(tp) ? tp->rp.kp.nmissed : tp->kp.nmissed); | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | static const struct seq_operations profile_seq_op = { | ||
797 | .start = probes_seq_start, | ||
798 | .next = probes_seq_next, | ||
799 | .stop = probes_seq_stop, | ||
800 | .show = probes_profile_seq_show | ||
801 | }; | ||
802 | |||
803 | static int profile_open(struct inode *inode, struct file *file) | ||
804 | { | ||
805 | return seq_open(file, &profile_seq_op); | ||
806 | } | ||
807 | |||
808 | static const struct file_operations kprobe_profile_ops = { | ||
809 | .owner = THIS_MODULE, | ||
810 | .open = profile_open, | ||
811 | .read = seq_read, | ||
812 | .llseek = seq_lseek, | ||
813 | .release = seq_release, | ||
814 | }; | ||
815 | |||
784 | /* Kprobe handler */ | 816 | /* Kprobe handler */ |
785 | static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | 817 | static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) |
786 | { | 818 | { |
@@ -791,6 +823,8 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
791 | unsigned long irq_flags; | 823 | unsigned long irq_flags; |
792 | struct ftrace_event_call *call = &tp->call; | 824 | struct ftrace_event_call *call = &tp->call; |
793 | 825 | ||
826 | tp->nhit++; | ||
827 | |||
794 | local_save_flags(irq_flags); | 828 | local_save_flags(irq_flags); |
795 | pc = preempt_count(); | 829 | pc = preempt_count(); |
796 | 830 | ||
@@ -1140,9 +1174,18 @@ static __init int init_kprobe_trace(void) | |||
1140 | entry = debugfs_create_file("kprobe_events", 0644, d_tracer, | 1174 | entry = debugfs_create_file("kprobe_events", 0644, d_tracer, |
1141 | NULL, &kprobe_events_ops); | 1175 | NULL, &kprobe_events_ops); |
1142 | 1176 | ||
1177 | /* Event list interface */ | ||
1143 | if (!entry) | 1178 | if (!entry) |
1144 | pr_warning("Could not create debugfs " | 1179 | pr_warning("Could not create debugfs " |
1145 | "'kprobe_events' entry\n"); | 1180 | "'kprobe_events' entry\n"); |
1181 | |||
1182 | /* Profile interface */ | ||
1183 | entry = debugfs_create_file("kprobe_profile", 0444, d_tracer, | ||
1184 | NULL, &kprobe_profile_ops); | ||
1185 | |||
1186 | if (!entry) | ||
1187 | pr_warning("Could not create debugfs " | ||
1188 | "'kprobe_profile' entry\n"); | ||
1146 | return 0; | 1189 | return 0; |
1147 | } | 1190 | } |
1148 | fs_initcall(init_kprobe_trace); | 1191 | fs_initcall(init_kprobe_trace); |