aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_kprobe.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 9f46e98ba8f2..c209c6ec34ca 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -281,6 +281,8 @@ trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file)
281static int 281static int
282disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) 282disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
283{ 283{
284 struct ftrace_event_file **old = NULL;
285 int wait = 0;
284 int ret = 0; 286 int ret = 0;
285 287
286 mutex_lock(&probe_enable_lock); 288 mutex_lock(&probe_enable_lock);
@@ -314,10 +316,7 @@ disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
314 } 316 }
315 317
316 rcu_assign_pointer(tp->files, new); 318 rcu_assign_pointer(tp->files, new);
317 319 wait = 1;
318 /* Make sure the probe is done with old files */
319 synchronize_sched();
320 kfree(old);
321 } else 320 } else
322 tp->flags &= ~TP_FLAG_PROFILE; 321 tp->flags &= ~TP_FLAG_PROFILE;
323 322
@@ -326,11 +325,25 @@ disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
326 disable_kretprobe(&tp->rp); 325 disable_kretprobe(&tp->rp);
327 else 326 else
328 disable_kprobe(&tp->rp.kp); 327 disable_kprobe(&tp->rp.kp);
328 wait = 1;
329 } 329 }
330 330
331 out_unlock: 331 out_unlock:
332 mutex_unlock(&probe_enable_lock); 332 mutex_unlock(&probe_enable_lock);
333 333
334 if (wait) {
335 /*
336 * Synchronize with kprobe_trace_func/kretprobe_trace_func
337 * to ensure disabled (all running handlers are finished).
338 * This is not only for kfree(), but also the caller,
339 * trace_remove_event_call() supposes it for releasing
340 * event_call related objects, which will be accessed in
341 * the kprobe_trace_func/kretprobe_trace_func.
342 */
343 synchronize_sched();
344 kfree(old); /* Ignored if link == NULL */
345 }
346
334 return ret; 347 return ret;
335} 348}
336 349