|
@@ -184,6 +184,7 @@ struct trace_probe {
|
|
|
struct kprobe kp;
|
|
|
struct kretprobe rp;
|
|
|
};
|
|
|
+ unsigned long nhit;
|
|
|
const char *symbol; /* symbol name */
|
|
|
struct ftrace_event_call call;
|
|
|
struct trace_event event;
|
|
@@ -781,6 +782,37 @@ static const struct file_operations kprobe_events_ops = {
|
|
|
.write = probes_write,
|
|
|
};
|
|
|
|
|
|
+/* Probes profiling interfaces */
|
|
|
+static int probes_profile_seq_show(struct seq_file *m, void *v)
|
|
|
+{
|
|
|
+ struct trace_probe *tp = v;
|
|
|
+
|
|
|
+ seq_printf(m, " %-44s %15lu %15lu\n", tp->call.name, tp->nhit,
|
|
|
+ probe_is_return(tp) ? tp->rp.kp.nmissed : tp->kp.nmissed);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static const struct seq_operations profile_seq_op = {
|
|
|
+ .start = probes_seq_start,
|
|
|
+ .next = probes_seq_next,
|
|
|
+ .stop = probes_seq_stop,
|
|
|
+ .show = probes_profile_seq_show
|
|
|
+};
|
|
|
+
|
|
|
+static int profile_open(struct inode *inode, struct file *file)
|
|
|
+{
|
|
|
+ return seq_open(file, &profile_seq_op);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct file_operations kprobe_profile_ops = {
|
|
|
+ .owner = THIS_MODULE,
|
|
|
+ .open = profile_open,
|
|
|
+ .read = seq_read,
|
|
|
+ .llseek = seq_lseek,
|
|
|
+ .release = seq_release,
|
|
|
+};
|
|
|
+
|
|
|
/* Kprobe handler */
|
|
|
static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
|
|
|
{
|
|
@@ -791,6 +823,8 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
|
|
|
unsigned long irq_flags;
|
|
|
struct ftrace_event_call *call = &tp->call;
|
|
|
|
|
|
+ tp->nhit++;
|
|
|
+
|
|
|
local_save_flags(irq_flags);
|
|
|
pc = preempt_count();
|
|
|
|
|
@@ -1140,9 +1174,18 @@ static __init int init_kprobe_trace(void)
|
|
|
entry = debugfs_create_file("kprobe_events", 0644, d_tracer,
|
|
|
NULL, &kprobe_events_ops);
|
|
|
|
|
|
+ /* Event list interface */
|
|
|
if (!entry)
|
|
|
pr_warning("Could not create debugfs "
|
|
|
"'kprobe_events' entry\n");
|
|
|
+
|
|
|
+ /* Profile interface */
|
|
|
+ entry = debugfs_create_file("kprobe_profile", 0444, d_tracer,
|
|
|
+ NULL, &kprobe_profile_ops);
|
|
|
+
|
|
|
+ if (!entry)
|
|
|
+ pr_warning("Could not create debugfs "
|
|
|
+ "'kprobe_profile' entry\n");
|
|
|
return 0;
|
|
|
}
|
|
|
fs_initcall(init_kprobe_trace);
|