diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 3811487e7a7a..243f6834d026 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -95,7 +95,7 @@ static __kprobes bool trace_probe_is_on_module(struct trace_probe *tp) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | static int register_probe_event(struct trace_probe *tp); | 97 | static int register_probe_event(struct trace_probe *tp); |
98 | static void unregister_probe_event(struct trace_probe *tp); | 98 | static int unregister_probe_event(struct trace_probe *tp); |
99 | 99 | ||
100 | static DEFINE_MUTEX(probe_lock); | 100 | static DEFINE_MUTEX(probe_lock); |
101 | static LIST_HEAD(probe_list); | 101 | static LIST_HEAD(probe_list); |
@@ -351,9 +351,12 @@ static int unregister_trace_probe(struct trace_probe *tp) | |||
351 | if (trace_probe_is_enabled(tp)) | 351 | if (trace_probe_is_enabled(tp)) |
352 | return -EBUSY; | 352 | return -EBUSY; |
353 | 353 | ||
354 | /* Will fail if probe is being used by ftrace or perf */ | ||
355 | if (unregister_probe_event(tp)) | ||
356 | return -EBUSY; | ||
357 | |||
354 | __unregister_trace_probe(tp); | 358 | __unregister_trace_probe(tp); |
355 | list_del(&tp->list); | 359 | list_del(&tp->list); |
356 | unregister_probe_event(tp); | ||
357 | 360 | ||
358 | return 0; | 361 | return 0; |
359 | } | 362 | } |
@@ -632,7 +635,9 @@ static int release_all_trace_probes(void) | |||
632 | /* TODO: Use batch unregistration */ | 635 | /* TODO: Use batch unregistration */ |
633 | while (!list_empty(&probe_list)) { | 636 | while (!list_empty(&probe_list)) { |
634 | tp = list_entry(probe_list.next, struct trace_probe, list); | 637 | tp = list_entry(probe_list.next, struct trace_probe, list); |
635 | unregister_trace_probe(tp); | 638 | ret = unregister_trace_probe(tp); |
639 | if (ret) | ||
640 | goto end; | ||
636 | free_trace_probe(tp); | 641 | free_trace_probe(tp); |
637 | } | 642 | } |
638 | 643 | ||
@@ -1247,11 +1252,15 @@ static int register_probe_event(struct trace_probe *tp) | |||
1247 | return ret; | 1252 | return ret; |
1248 | } | 1253 | } |
1249 | 1254 | ||
1250 | static void unregister_probe_event(struct trace_probe *tp) | 1255 | static int unregister_probe_event(struct trace_probe *tp) |
1251 | { | 1256 | { |
1257 | int ret; | ||
1258 | |||
1252 | /* tp->event is unregistered in trace_remove_event_call() */ | 1259 | /* tp->event is unregistered in trace_remove_event_call() */ |
1253 | trace_remove_event_call(&tp->call); | 1260 | ret = trace_remove_event_call(&tp->call); |
1254 | kfree(tp->call.print_fmt); | 1261 | if (!ret) |
1262 | kfree(tp->call.print_fmt); | ||
1263 | return ret; | ||
1255 | } | 1264 | } |
1256 | 1265 | ||
1257 | /* Make a debugfs interface for controlling probe points */ | 1266 | /* Make a debugfs interface for controlling probe points */ |