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 <mhira...@kernel.org>
---
 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 3a7c73c40007..a49583ece5fd 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -609,12 +609,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;
 }

Reply via email to