|
@@ -893,6 +893,9 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file,
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
if (file) {
|
|
if (file) {
|
|
|
|
+ if (tu->tp.flags & TP_FLAG_PROFILE)
|
|
|
|
+ return -EINTR;
|
|
|
|
+
|
|
link = kmalloc(sizeof(*link), GFP_KERNEL);
|
|
link = kmalloc(sizeof(*link), GFP_KERNEL);
|
|
if (!link)
|
|
if (!link)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -901,29 +904,40 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file,
|
|
list_add_tail_rcu(&link->list, &tu->tp.files);
|
|
list_add_tail_rcu(&link->list, &tu->tp.files);
|
|
|
|
|
|
tu->tp.flags |= TP_FLAG_TRACE;
|
|
tu->tp.flags |= TP_FLAG_TRACE;
|
|
- } else
|
|
|
|
- tu->tp.flags |= TP_FLAG_PROFILE;
|
|
|
|
|
|
+ } else {
|
|
|
|
+ if (tu->tp.flags & TP_FLAG_TRACE)
|
|
|
|
+ return -EINTR;
|
|
|
|
|
|
- ret = uprobe_buffer_enable();
|
|
|
|
- if (ret < 0)
|
|
|
|
- return ret;
|
|
|
|
|
|
+ tu->tp.flags |= TP_FLAG_PROFILE;
|
|
|
|
+ }
|
|
|
|
|
|
WARN_ON(!uprobe_filter_is_empty(&tu->filter));
|
|
WARN_ON(!uprobe_filter_is_empty(&tu->filter));
|
|
|
|
|
|
if (enabled)
|
|
if (enabled)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+ ret = uprobe_buffer_enable();
|
|
|
|
+ if (ret)
|
|
|
|
+ goto err_flags;
|
|
|
|
+
|
|
tu->consumer.filter = filter;
|
|
tu->consumer.filter = filter;
|
|
ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
|
|
ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
|
|
- if (ret) {
|
|
|
|
- if (file) {
|
|
|
|
- list_del(&link->list);
|
|
|
|
- kfree(link);
|
|
|
|
- tu->tp.flags &= ~TP_FLAG_TRACE;
|
|
|
|
- } else
|
|
|
|
- tu->tp.flags &= ~TP_FLAG_PROFILE;
|
|
|
|
- }
|
|
|
|
|
|
+ if (ret)
|
|
|
|
+ goto err_buffer;
|
|
|
|
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ err_buffer:
|
|
|
|
+ uprobe_buffer_disable();
|
|
|
|
+
|
|
|
|
+ err_flags:
|
|
|
|
+ if (file) {
|
|
|
|
+ list_del(&link->list);
|
|
|
|
+ kfree(link);
|
|
|
|
+ tu->tp.flags &= ~TP_FLAG_TRACE;
|
|
|
|
+ } else {
|
|
|
|
+ tu->tp.flags &= ~TP_FLAG_PROFILE;
|
|
|
|
+ }
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1201,12 +1215,6 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
|
|
|
|
|
|
current->utask->vaddr = (unsigned long) &udd;
|
|
current->utask->vaddr = (unsigned long) &udd;
|
|
|
|
|
|
-#ifdef CONFIG_PERF_EVENTS
|
|
|
|
- if ((tu->tp.flags & TP_FLAG_TRACE) == 0 &&
|
|
|
|
- !uprobe_perf_filter(&tu->consumer, 0, current->mm))
|
|
|
|
- return UPROBE_HANDLER_REMOVE;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
if (WARN_ON_ONCE(!uprobe_cpu_buffer))
|
|
if (WARN_ON_ONCE(!uprobe_cpu_buffer))
|
|
return 0;
|
|
return 0;
|
|
|
|
|