aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/trace/kprobetrace.txt8
-rw-r--r--kernel/trace/trace_kprobe.c43
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
73Event 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,
78the third is the number of probe miss-hits.
79
80
73Usage examples 81Usage examples
74-------------- 82--------------
75To add a probe as a new event, write a new definition to kprobe_events 83To 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 */
786static 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
796static 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
803static int profile_open(struct inode *inode, struct file *file)
804{
805 return seq_open(file, &profile_seq_op);
806}
807
808static 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 */
785static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) 817static __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}
1148fs_initcall(init_kprobe_trace); 1191fs_initcall(init_kprobe_trace);