* [for-next][PATCH 1/4] tracing/uprobes: Revert "Support mix of ftrace and perf"
2014-06-30 21:50 [for-next][PATCH 0/4] [3.16] tracing/uprobes: Fixes Steven Rostedt
@ 2014-06-30 21:50 ` Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 2/4] uprobes: Change unregister/apply to WARN() if uprobe/consumer is gone Steven Rostedt
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2014-06-30 21:50 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov, Tom Zanussi,
zhangwei(Jovi),
Namhyung Kim, Srikar Dronamraju, Masami Hiramatsu
[-- Attachment #1: 0001-tracing-uprobes-Revert-Support-mix-of-ftrace-and-per.patch --]
[-- Type: text/plain, Size: 2177 bytes --]
From: Oleg Nesterov <oleg@redhat.com>
This reverts commit 43fe98913c9f67e3b523615ee3316f9520a623e0.
This patch is very wrong. Firstly, this change leads to unbalanced
uprobe_unregister(). Just for example,
# perf probe -x /lib/libc.so.6 syscall
# echo 1 >> /sys/kernel/debug/tracing/events/probe_libc/enable
# perf record -e probe_libc:syscall whatever
after that uprobe is dead (unregistered) but the user of ftrace/perf
can't know this, and it looks as if nobody hits this probe.
This would be easy to fix, but there are other reasons why it is not
simple to mix ftrace and perf. If nothing else, they can't share the
same ->consumer.filter. This is fixable too, but probably we need to
fix the poorly designed uprobe_register() interface first. At least
"register" and "apply" should be clearly separated.
Link: http://lkml.kernel.org/p/20140627170136.GA18319@redhat.com
Cc: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: "zhangwei(Jovi)" <jovi.zhangwei@huawei.com>
Cc: stable@vger.kernel.org # v3.14
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_uprobe.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 04fdb5de823c..08e7970bf3f9 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -893,6 +893,9 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file,
int ret;
if (file) {
+ if (tu->tp.flags & TP_FLAG_PROFILE)
+ return -EINTR;
+
link = kmalloc(sizeof(*link), GFP_KERNEL);
if (!link)
return -ENOMEM;
@@ -901,8 +904,12 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file,
list_add_tail_rcu(&link->list, &tu->tp.files);
tu->tp.flags |= TP_FLAG_TRACE;
- } else
+ } else {
+ if (tu->tp.flags & TP_FLAG_TRACE)
+ return -EINTR;
+
tu->tp.flags |= TP_FLAG_PROFILE;
+ }
ret = uprobe_buffer_enable();
if (ret < 0)
--
2.0.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [for-next][PATCH 2/4] uprobes: Change unregister/apply to WARN() if uprobe/consumer is gone
2014-06-30 21:50 [for-next][PATCH 0/4] [3.16] tracing/uprobes: Fixes Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 1/4] tracing/uprobes: Revert "Support mix of ftrace and perf" Steven Rostedt
@ 2014-06-30 21:50 ` Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 3/4] tracing/uprobes: Kill the bogus UPROBE_HANDLER_REMOVE code in uprobe_dispatcher() Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 4/4] tracing/uprobes: Fix the usage of uprobe_buffer_enable() in probe_event_enable() Steven Rostedt
3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2014-06-30 21:50 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov, Namhyung Kim,
Srikar Dronamraju
[-- Attachment #1: 0002-uprobes-Change-unregister-apply-to-WARN-if-uprobe-co.patch --]
[-- Type: text/plain, Size: 1748 bytes --]
From: Oleg Nesterov <oleg@redhat.com>
Add WARN_ON's into uprobe_unregister() and uprobe_apply() to ensure
that nobody tries to play with the dead uprobe/consumer. This helps
to catch the bugs like the one fixed by the previous patch.
In the longer term we should fix this poorly designed interface.
uprobe_register() should return "struct uprobe *" which should be
passed to apply/unregister. Plus other semantic changes, see the
changelog in commit 41ccba029e94.
Link: http://lkml.kernel.org/p/20140627170140.GA18322@redhat.com
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/events/uprobes.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index c445e392e93f..6f3254e8c137 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -846,7 +846,7 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u
{
int err;
- if (!consumer_del(uprobe, uc)) /* WARN? */
+ if (WARN_ON(!consumer_del(uprobe, uc)))
return;
err = register_for_each_vma(uprobe, NULL);
@@ -927,7 +927,7 @@ int uprobe_apply(struct inode *inode, loff_t offset,
int ret = -ENOENT;
uprobe = find_uprobe(inode, offset);
- if (!uprobe)
+ if (WARN_ON(!uprobe))
return ret;
down_write(&uprobe->register_rwsem);
@@ -952,7 +952,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
struct uprobe *uprobe;
uprobe = find_uprobe(inode, offset);
- if (!uprobe)
+ if (WARN_ON(!uprobe))
return;
down_write(&uprobe->register_rwsem);
--
2.0.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [for-next][PATCH 3/4] tracing/uprobes: Kill the bogus UPROBE_HANDLER_REMOVE code in uprobe_dispatcher()
2014-06-30 21:50 [for-next][PATCH 0/4] [3.16] tracing/uprobes: Fixes Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 1/4] tracing/uprobes: Revert "Support mix of ftrace and perf" Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 2/4] uprobes: Change unregister/apply to WARN() if uprobe/consumer is gone Steven Rostedt
@ 2014-06-30 21:50 ` Steven Rostedt
2014-06-30 21:50 ` [for-next][PATCH 4/4] tracing/uprobes: Fix the usage of uprobe_buffer_enable() in probe_event_enable() Steven Rostedt
3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2014-06-30 21:50 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov, Namhyung Kim,
Srikar Dronamraju
[-- Attachment #1: 0003-tracing-uprobes-Kill-the-bogus-UPROBE_HANDLER_REMOVE.patch --]
[-- Type: text/plain, Size: 1489 bytes --]
From: Oleg Nesterov <oleg@redhat.com>
I do not know why dd9fa555d7bb "tracing/uprobes: Move argument fetching
to uprobe_dispatcher()" added the UPROBE_HANDLER_REMOVE, but it looks
wrong.
OK, perhaps it makes sense to avoid store_trace_args() if the tracee is
nacked by uprobe_perf_filter(). But then we should kill the same code
in uprobe_perf_func() and unify the TRACE/PROFILE filtering (we need to
do this anyway to mix perf/ftrace). Until then this code actually adds
the pessimization because uprobe_perf_filter() will be called twice and
return T in likely case.
Link: http://lkml.kernel.org/p/20140627170143.GA18329@redhat.com
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_uprobe.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 08e7970bf3f9..c4cf0abd60ba 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -1208,12 +1208,6 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
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))
return 0;
--
2.0.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [for-next][PATCH 4/4] tracing/uprobes: Fix the usage of uprobe_buffer_enable() in probe_event_enable()
2014-06-30 21:50 [for-next][PATCH 0/4] [3.16] tracing/uprobes: Fixes Steven Rostedt
` (2 preceding siblings ...)
2014-06-30 21:50 ` [for-next][PATCH 3/4] tracing/uprobes: Kill the bogus UPROBE_HANDLER_REMOVE code in uprobe_dispatcher() Steven Rostedt
@ 2014-06-30 21:50 ` Steven Rostedt
3 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2014-06-30 21:50 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov, Namhyung Kim,
Srikar Dronamraju, Masami Hiramatsu
[-- Attachment #1: 0004-tracing-uprobes-Fix-the-usage-of-uprobe_buffer_enabl.patch --]
[-- Type: text/plain, Size: 2000 bytes --]
From: Oleg Nesterov <oleg@redhat.com>
The usage of uprobe_buffer_enable() added by dcad1a20 is very wrong,
1. uprobe_buffer_enable() and uprobe_buffer_disable() are not balanced,
_enable() should be called only if !enabled.
2. If uprobe_buffer_enable() fails probe_event_enable() should clear
tp.flags and free event_file_link.
3. If uprobe_register() fails it should do uprobe_buffer_disable().
Link: http://lkml.kernel.org/p/20140627170146.GA18332@redhat.com
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Fixes: dcad1a204f72 "tracing/uprobes: Fetch args before reserving a ring buffer"
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_uprobe.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index c4cf0abd60ba..3c9b97e6b1f4 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -911,26 +911,33 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file,
tu->tp.flags |= TP_FLAG_PROFILE;
}
- ret = uprobe_buffer_enable();
- if (ret < 0)
- return ret;
-
WARN_ON(!uprobe_filter_is_empty(&tu->filter));
if (enabled)
return 0;
+ ret = uprobe_buffer_enable();
+ if (ret)
+ goto err_flags;
+
tu->consumer.filter = filter;
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;
}
--
2.0.0
^ permalink raw reply [flat|nested] 5+ messages in thread