tracing/probe: Add trace_probe init and free functions
Add common trace_probe init and cleanup function in trace_probe.c, and use it from trace_kprobe.c and trace_uprobe.c Link: http://lkml.kernel.org/r/155931582664.28323.5934870189034740822.stgit@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
		
							parent
							
								
									b4d4b96be8
								
							
						
					
					
						commit
						455b289973
					
				| @ -197,6 +197,16 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs); | ||||
| static int kretprobe_dispatcher(struct kretprobe_instance *ri, | ||||
| 				struct pt_regs *regs); | ||||
| 
 | ||||
| static void free_trace_kprobe(struct trace_kprobe *tk) | ||||
| { | ||||
| 	if (tk) { | ||||
| 		trace_probe_cleanup(&tk->tp); | ||||
| 		kfree(tk->symbol); | ||||
| 		free_percpu(tk->nhit); | ||||
| 		kfree(tk); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Allocate new trace_probe and initialize it (including kprobes). | ||||
|  */ | ||||
| @ -235,49 +245,17 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group, | ||||
| 
 | ||||
| 	tk->rp.maxactive = maxactive; | ||||
| 
 | ||||
| 	if (!event || !group) { | ||||
| 		ret = -EINVAL; | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	tk->tp.call.class = &tk->tp.class; | ||||
| 	tk->tp.call.name = kstrdup(event, GFP_KERNEL); | ||||
| 	if (!tk->tp.call.name) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	tk->tp.class.system = kstrdup(group, GFP_KERNEL); | ||||
| 	if (!tk->tp.class.system) | ||||
| 	ret = trace_probe_init(&tk->tp, event, group); | ||||
| 	if (ret < 0) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	dyn_event_init(&tk->devent, &trace_kprobe_ops); | ||||
| 	INIT_LIST_HEAD(&tk->tp.files); | ||||
| 	return tk; | ||||
| error: | ||||
| 	kfree(tk->tp.call.name); | ||||
| 	kfree(tk->symbol); | ||||
| 	free_percpu(tk->nhit); | ||||
| 	kfree(tk); | ||||
| 	free_trace_kprobe(tk); | ||||
| 	return ERR_PTR(ret); | ||||
| } | ||||
| 
 | ||||
| static void free_trace_kprobe(struct trace_kprobe *tk) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	if (!tk) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (i = 0; i < tk->tp.nr_args; i++) | ||||
| 		traceprobe_free_probe_arg(&tk->tp.args[i]); | ||||
| 
 | ||||
| 	kfree(tk->tp.call.class->system); | ||||
| 	kfree(tk->tp.call.name); | ||||
| 	kfree(tk->tp.call.print_fmt); | ||||
| 	kfree(tk->symbol); | ||||
| 	free_percpu(tk->nhit); | ||||
| 	kfree(tk); | ||||
| } | ||||
| 
 | ||||
| static struct trace_kprobe *find_trace_kprobe(const char *event, | ||||
| 					      const char *group) | ||||
| { | ||||
| @ -1400,7 +1378,6 @@ static struct trace_event_functions kprobe_funcs = { | ||||
| static inline void init_trace_event_call(struct trace_kprobe *tk, | ||||
| 					 struct trace_event_call *call) | ||||
| { | ||||
| 	INIT_LIST_HEAD(&call->class->fields); | ||||
| 	if (trace_kprobe_is_return(tk)) { | ||||
| 		call->event.funcs = &kretprobe_funcs; | ||||
| 		call->class->define_fields = kretprobe_event_define_fields; | ||||
|  | ||||
| @ -884,3 +884,39 @@ int traceprobe_define_arg_fields(struct trace_event_call *event_call, | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void trace_probe_cleanup(struct trace_probe *tp) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < tp->nr_args; i++) | ||||
| 		traceprobe_free_probe_arg(&tp->args[i]); | ||||
| 
 | ||||
| 	kfree(tp->call.class->system); | ||||
| 	kfree(tp->call.name); | ||||
| 	kfree(tp->call.print_fmt); | ||||
| } | ||||
| 
 | ||||
| int trace_probe_init(struct trace_probe *tp, const char *event, | ||||
| 		     const char *group) | ||||
| { | ||||
| 	if (!event || !group) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	tp->call.class = &tp->class; | ||||
| 	tp->call.name = kstrdup(event, GFP_KERNEL); | ||||
| 	if (!tp->call.name) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	tp->class.system = kstrdup(group, GFP_KERNEL); | ||||
| 	if (!tp->class.system) { | ||||
| 		kfree(tp->call.name); | ||||
| 		tp->call.name = NULL; | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	INIT_LIST_HEAD(&tp->files); | ||||
| 	INIT_LIST_HEAD(&tp->class.fields); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -248,6 +248,10 @@ static inline bool trace_probe_is_registered(struct trace_probe *tp) | ||||
| 	return !!(tp->flags & TP_FLAG_REGISTERED); | ||||
| } | ||||
| 
 | ||||
| int trace_probe_init(struct trace_probe *tp, const char *event, | ||||
| 		     const char *group); | ||||
| void trace_probe_cleanup(struct trace_probe *tp); | ||||
| 
 | ||||
| /* Check the name is good for event/group/fields */ | ||||
| static inline bool is_good_name(const char *name) | ||||
| { | ||||
|  | ||||
| @ -300,25 +300,17 @@ static struct trace_uprobe * | ||||
| alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret) | ||||
| { | ||||
| 	struct trace_uprobe *tu; | ||||
| 
 | ||||
| 	if (!event || !group) | ||||
| 		return ERR_PTR(-EINVAL); | ||||
| 	int ret; | ||||
| 
 | ||||
| 	tu = kzalloc(SIZEOF_TRACE_UPROBE(nargs), GFP_KERNEL); | ||||
| 	if (!tu) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	tu->tp.call.class = &tu->tp.class; | ||||
| 	tu->tp.call.name = kstrdup(event, GFP_KERNEL); | ||||
| 	if (!tu->tp.call.name) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	tu->tp.class.system = kstrdup(group, GFP_KERNEL); | ||||
| 	if (!tu->tp.class.system) | ||||
| 	ret = trace_probe_init(&tu->tp, event, group); | ||||
| 	if (ret < 0) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	dyn_event_init(&tu->devent, &trace_uprobe_ops); | ||||
| 	INIT_LIST_HEAD(&tu->tp.files); | ||||
| 	tu->consumer.handler = uprobe_dispatcher; | ||||
| 	if (is_ret) | ||||
| 		tu->consumer.ret_handler = uretprobe_dispatcher; | ||||
| @ -326,26 +318,18 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret) | ||||
| 	return tu; | ||||
| 
 | ||||
| error: | ||||
| 	kfree(tu->tp.call.name); | ||||
| 	kfree(tu); | ||||
| 
 | ||||
| 	return ERR_PTR(-ENOMEM); | ||||
| 	return ERR_PTR(ret); | ||||
| } | ||||
| 
 | ||||
| static void free_trace_uprobe(struct trace_uprobe *tu) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	if (!tu) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (i = 0; i < tu->tp.nr_args; i++) | ||||
| 		traceprobe_free_probe_arg(&tu->tp.args[i]); | ||||
| 
 | ||||
| 	path_put(&tu->path); | ||||
| 	kfree(tu->tp.call.class->system); | ||||
| 	kfree(tu->tp.call.name); | ||||
| 	kfree(tu->tp.call.print_fmt); | ||||
| 	trace_probe_cleanup(&tu->tp); | ||||
| 	kfree(tu->filename); | ||||
| 	kfree(tu); | ||||
| } | ||||
| @ -1351,7 +1335,6 @@ static struct trace_event_functions uprobe_funcs = { | ||||
| static inline void init_trace_event_call(struct trace_uprobe *tu, | ||||
| 					 struct trace_event_call *call) | ||||
| { | ||||
| 	INIT_LIST_HEAD(&call->class->fields); | ||||
| 	call->event.funcs = &uprobe_funcs; | ||||
| 	call->class->define_fields = uprobe_event_define_fields; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user