diff options
Diffstat (limited to 'kernel')
| -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 */ |
