Add a busy check loop in cleanup_all_probes() before trying to remove all events in uprobe_events as same as kprobe_events does.
Without this change, writing null to uprobe_events will try to remove events but if one of them is enabled, it stopped there but some of events are already cleared. With this change, writing null to uprobe_events make sure all events are not enabled before removing events. So, it clears all events, or return an error (-EBUSY) with keeping all events. Signed-off-by: Masami Hiramatsu <[email protected]> --- kernel/trace/trace_uprobe.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 31ea48eceda1..b708e4ff7ea7 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -587,12 +587,19 @@ static int cleanup_all_probes(void) int ret = 0; mutex_lock(&uprobe_lock); + /* Ensure no probe is in use. */ + list_for_each_entry(tu, &uprobe_list, list) + if (trace_probe_is_enabled(&tu->tp)) { + ret = -EBUSY; + goto end; + } while (!list_empty(&uprobe_list)) { tu = list_entry(uprobe_list.next, struct trace_uprobe, list); ret = unregister_trace_uprobe(tu); if (ret) break; } +end: mutex_unlock(&uprobe_lock); return ret; }

