diff options
author | Oleg Nesterov <oleg@redhat.com> | 2014-04-24 07:33:31 -0400 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2014-04-30 13:10:42 -0400 |
commit | 927d687480ab7e43d73a003bab58803fc67717d9 (patch) | |
tree | 22b7b6454f2b3bfc1994a0741fa41884b91966cd /kernel/trace | |
parent | ce5f36a58fd1d92cb945cf2568751d40e8598508 (diff) |
uprobes/tracing: Fix uprobe_perf_open() on uprobe_apply() failure
uprobe_perf_open()->uprobe_apply() can fail, but this error is wrongly
ignored. Change uprobe_perf_open() to do uprobe_perf_close() and return
the error code in this case.
Change uprobe_perf_close() to propogate the error from uprobe_apply()
as well, although it should not fail.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/trace_uprobe.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 51bd071eaca0..5a7f1a6b3b8b 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
@@ -1026,7 +1026,7 @@ static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event) | |||
1026 | write_unlock(&tu->filter.rwlock); | 1026 | write_unlock(&tu->filter.rwlock); |
1027 | 1027 | ||
1028 | if (!done) | 1028 | if (!done) |
1029 | uprobe_apply(tu->inode, tu->offset, &tu->consumer, false); | 1029 | return uprobe_apply(tu->inode, tu->offset, &tu->consumer, false); |
1030 | 1030 | ||
1031 | return 0; | 1031 | return 0; |
1032 | } | 1032 | } |
@@ -1034,6 +1034,7 @@ static int uprobe_perf_close(struct trace_uprobe *tu, struct perf_event *event) | |||
1034 | static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event) | 1034 | static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event) |
1035 | { | 1035 | { |
1036 | bool done; | 1036 | bool done; |
1037 | int err; | ||
1037 | 1038 | ||
1038 | write_lock(&tu->filter.rwlock); | 1039 | write_lock(&tu->filter.rwlock); |
1039 | if (event->hw.tp_target) { | 1040 | if (event->hw.tp_target) { |
@@ -1055,10 +1056,13 @@ static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event *event) | |||
1055 | } | 1056 | } |
1056 | write_unlock(&tu->filter.rwlock); | 1057 | write_unlock(&tu->filter.rwlock); |
1057 | 1058 | ||
1058 | if (!done) | 1059 | err = 0; |
1059 | uprobe_apply(tu->inode, tu->offset, &tu->consumer, true); | 1060 | if (!done) { |
1060 | 1061 | err = uprobe_apply(tu->inode, tu->offset, &tu->consumer, true); | |
1061 | return 0; | 1062 | if (err) |
1063 | uprobe_perf_close(tu, event); | ||
1064 | } | ||
1065 | return err; | ||
1062 | } | 1066 | } |
1063 | 1067 | ||
1064 | static bool uprobe_perf_filter(struct uprobe_consumer *uc, | 1068 | static bool uprobe_perf_filter(struct uprobe_consumer *uc, |