aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-03-30 13:25:23 -0400
committerOleg Nesterov <oleg@redhat.com>2013-04-13 09:32:02 -0400
commitc1ae5c75e1034070b203dc9d4ad77ce196166a6c (patch)
treea7cd4e28f3562037c1f76797234a6a2d2ce7a24e
parenta51cc6041773dd88ff35608f54274bfd6ac68652 (diff)
uprobes/tracing: Introduce is_ret_probe() and uretprobe_dispatcher()
Create the new functions we need to support uretprobes, and change alloc_trace_uprobe() to initialize consumer.ret_handler if the new "is_ret" argument is true. Curently this argument is always false, so the new code is never called and is_ret_probe(tu) is false too. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Tested-by: Anton Arapov <anton@redhat.com>
-rw-r--r--kernel/trace/trace_uprobe.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 0c0f0a7d4ff1..72aa45e50d48 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -76,6 +76,8 @@ static DEFINE_MUTEX(uprobe_lock);
76static LIST_HEAD(uprobe_list); 76static LIST_HEAD(uprobe_list);
77 77
78static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs); 78static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
79static int uretprobe_dispatcher(struct uprobe_consumer *con,
80 unsigned long func, struct pt_regs *regs);
79 81
80static inline void init_trace_uprobe_filter(struct trace_uprobe_filter *filter) 82static inline void init_trace_uprobe_filter(struct trace_uprobe_filter *filter)
81{ 83{
@@ -89,11 +91,16 @@ static inline bool uprobe_filter_is_empty(struct trace_uprobe_filter *filter)
89 return !filter->nr_systemwide && list_empty(&filter->perf_events); 91 return !filter->nr_systemwide && list_empty(&filter->perf_events);
90} 92}
91 93
94static inline bool is_ret_probe(struct trace_uprobe *tu)
95{
96 return tu->consumer.ret_handler != NULL;
97}
98
92/* 99/*
93 * Allocate new trace_uprobe and initialize it (including uprobes). 100 * Allocate new trace_uprobe and initialize it (including uprobes).
94 */ 101 */
95static struct trace_uprobe * 102static struct trace_uprobe *
96alloc_trace_uprobe(const char *group, const char *event, int nargs) 103alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret)
97{ 104{
98 struct trace_uprobe *tu; 105 struct trace_uprobe *tu;
99 106
@@ -118,6 +125,8 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs)
118 125
119 INIT_LIST_HEAD(&tu->list); 126 INIT_LIST_HEAD(&tu->list);
120 tu->consumer.handler = uprobe_dispatcher; 127 tu->consumer.handler = uprobe_dispatcher;
128 if (is_ret)
129 tu->consumer.ret_handler = uretprobe_dispatcher;
121 init_trace_uprobe_filter(&tu->filter); 130 init_trace_uprobe_filter(&tu->filter);
122 return tu; 131 return tu;
123 132
@@ -315,7 +324,7 @@ static int create_trace_uprobe(int argc, char **argv)
315 kfree(tail); 324 kfree(tail);
316 } 325 }
317 326
318 tu = alloc_trace_uprobe(group, event, argc); 327 tu = alloc_trace_uprobe(group, event, argc, false);
319 if (IS_ERR(tu)) { 328 if (IS_ERR(tu)) {
320 pr_info("Failed to allocate trace_uprobe.(%d)\n", (int)PTR_ERR(tu)); 329 pr_info("Failed to allocate trace_uprobe.(%d)\n", (int)PTR_ERR(tu));
321 ret = PTR_ERR(tu); 330 ret = PTR_ERR(tu);
@@ -530,6 +539,12 @@ static int uprobe_trace_func(struct trace_uprobe *tu, struct pt_regs *regs)
530 return 0; 539 return 0;
531} 540}
532 541
542static void uretprobe_trace_func(struct trace_uprobe *tu, unsigned long func,
543 struct pt_regs *regs)
544{
545 uprobe_trace_print(tu, func, regs);
546}
547
533/* Event entry printers */ 548/* Event entry printers */
534static enum print_line_t 549static enum print_line_t
535print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *event) 550print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *event)
@@ -800,6 +815,12 @@ static int uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs)
800 uprobe_perf_print(tu, 0, regs); 815 uprobe_perf_print(tu, 0, regs);
801 return 0; 816 return 0;
802} 817}
818
819static void uretprobe_perf_func(struct trace_uprobe *tu, unsigned long func,
820 struct pt_regs *regs)
821{
822 uprobe_perf_print(tu, func, regs);
823}
803#endif /* CONFIG_PERF_EVENTS */ 824#endif /* CONFIG_PERF_EVENTS */
804 825
805static 826static
@@ -854,6 +875,23 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
854 return ret; 875 return ret;
855} 876}
856 877
878static int uretprobe_dispatcher(struct uprobe_consumer *con,
879 unsigned long func, struct pt_regs *regs)
880{
881 struct trace_uprobe *tu;
882
883 tu = container_of(con, struct trace_uprobe, consumer);
884
885 if (tu->flags & TP_FLAG_TRACE)
886 uretprobe_trace_func(tu, func, regs);
887
888#ifdef CONFIG_PERF_EVENTS
889 if (tu->flags & TP_FLAG_PROFILE)
890 uretprobe_perf_func(tu, func, regs);
891#endif
892 return 0;
893}
894
857static struct trace_event_functions uprobe_funcs = { 895static struct trace_event_functions uprobe_funcs = {
858 .trace = print_uprobe_event 896 .trace = print_uprobe_event
859}; 897};