From: Masami Hiramatsu <masami.hiramatsu...@hitachi.com>

Wait for disabling all running kprobe handlers when a kprobe
event is disabled, since the caller, trace_remove_event_call()
supposes that a removing event is disabled completely by
disabling the event.
With this change, ftrace can ensure that there is no running
event handlers after disabling it.

Link: http://lkml.kernel.org/r/20130709093526.20138.93100.stgit@mhiramat-M0-7522

Signed-off-by: Masami Hiramatsu <masami.hiramatsu...@hitachi.com>
Signed-off-by: Steven Rostedt <rost...@goodmis.org>
---
 kernel/trace/trace_kprobe.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index ae6ce83..3811487 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -243,11 +243,11 @@ find_event_file_link(struct trace_probe *tp, struct 
ftrace_event_file *file)
 static int
 disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
 {
+       struct event_file_link *link = NULL;
+       int wait = 0;
        int ret = 0;
 
        if (file) {
-               struct event_file_link *link;
-
                link = find_event_file_link(tp, file);
                if (!link) {
                        ret = -EINVAL;
@@ -255,10 +255,7 @@ disable_trace_probe(struct trace_probe *tp, struct 
ftrace_event_file *file)
                }
 
                list_del_rcu(&link->list);
-               /* synchronize with kprobe_trace_func/kretprobe_trace_func */
-               synchronize_sched();
-               kfree(link);
-
+               wait = 1;
                if (!list_empty(&tp->files))
                        goto out;
 
@@ -271,8 +268,22 @@ disable_trace_probe(struct trace_probe *tp, struct 
ftrace_event_file *file)
                        disable_kretprobe(&tp->rp);
                else
                        disable_kprobe(&tp->rp.kp);
+               wait = 1;
        }
  out:
+       if (wait) {
+               /*
+                * Synchronize with kprobe_trace_func/kretprobe_trace_func
+                * to ensure disabled (all running handlers are finished).
+                * This is not only for kfree(), but also the caller,
+                * trace_remove_event_call() supposes it for releasing
+                * event_call related objects, which will be accessed in
+                * the kprobe_trace_func/kretprobe_trace_func.
+                */
+               synchronize_sched();
+               kfree(link);    /* Ignored if link == NULL */
+       }
+
        return ret;
 }
 
-- 
1.7.10.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to