public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups
@ 2013-01-28 18:24 Oleg Nesterov
  2013-01-28 18:24 ` [PATCH 1/5] uprobes: Ensure inode != NULL in create_trace_uprobe() Oleg Nesterov
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Oleg Nesterov @ 2013-01-28 18:24 UTC (permalink / raw)
  To: Ingo Molnar, Srikar Dronamraju, Steven Rostedt
  Cc: Anton Arapov, Frank Eigler, Josh Stone, Masami Hiramatsu,
	Suzuki K. Poulose, linux-kernel

Hello.

On top of
"[PATCH 0/4] uprobes: Teach debug/tracing/uprobe_events to do the filtering"
I sent yesterday.

I tried to test that series, seems to work...

This one tries to cleanup the code. No functional changes. Almost untested
so far, but please review.

Since I had to look at this code, I simply can't resist. uprobe_trace_consumer
complicates the code for no reason and imho should die.

Oleg.

 kernel/trace/trace_uprobe.c |  146 ++++++++++++++++++-------------------------
 1 files changed, 62 insertions(+), 84 deletions(-)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] uprobes: Ensure inode != NULL in create_trace_uprobe()
  2013-01-28 18:24 [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups Oleg Nesterov
@ 2013-01-28 18:24 ` Oleg Nesterov
  2013-01-28 18:24 ` [PATCH 2/5] uprobes: Introduce trace_uprobe->enabled Oleg Nesterov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2013-01-28 18:24 UTC (permalink / raw)
  To: Ingo Molnar, Srikar Dronamraju, Steven Rostedt
  Cc: Anton Arapov, Frank Eigler, Josh Stone, Masami Hiramatsu,
	Suzuki K. Poulose, linux-kernel

probe_event_enable/disable() check tu->inode != NULL at the start.
This is ugly, if igrab() can fail create_trace_uprobe() should not
succeed and "postpone" the failure.

Note: alloc_uprobe() should probably check igrab() != NULL as well.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/trace/trace_uprobe.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 0c05288..f49ccf9 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -349,6 +349,8 @@ static int create_trace_uprobe(int argc, char **argv)
 
 	inode = igrab(path.dentry->d_inode);
 	path_put(&path);
+	if (!inode)
+		goto fail_address_parse;
 
 	ret = kstrtoul(arg, 0, &offset);
 	if (ret)
@@ -645,7 +647,7 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag)
 	struct uprobe_trace_consumer *utc;
 	int ret = 0;
 
-	if (!tu->inode || tu->consumer)
+	if (tu->consumer)
 		return -EINTR;
 
 	utc = kzalloc(sizeof(struct uprobe_trace_consumer), GFP_KERNEL);
@@ -670,7 +672,7 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag)
 
 static void probe_event_disable(struct trace_uprobe *tu, int flag)
 {
-	if (!tu->inode || !tu->consumer)
+	if (!tu->consumer)
 		return;
 
 	uprobe_unregister(tu->inode, tu->offset, &tu->consumer->cons);
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] uprobes: Introduce trace_uprobe->enabled
  2013-01-28 18:24 [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups Oleg Nesterov
  2013-01-28 18:24 ` [PATCH 1/5] uprobes: Ensure inode != NULL in create_trace_uprobe() Oleg Nesterov
@ 2013-01-28 18:24 ` Oleg Nesterov
  2013-01-28 18:24 ` [PATCH 3/5] uprobes: Kill uprobe_trace_consumer, embed uprobe_consumer into trace_uprobe Oleg Nesterov
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2013-01-28 18:24 UTC (permalink / raw)
  To: Ingo Molnar, Srikar Dronamraju, Steven Rostedt
  Cc: Anton Arapov, Frank Eigler, Josh Stone, Masami Hiramatsu,
	Suzuki K. Poulose, linux-kernel

probe_event_enable/disable() check tu->consumer != NULL to avoid
the wrong uprobe_register/unregister().

We are going to kill uprobe_trace_consumer, so we add the explicit
trace_uprobe->enabled member which can be used instead.

This is the temporary change to simplify the next patch, the new
member will go away after cleanups.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/trace/trace_uprobe.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index f49ccf9..c430d01 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -46,6 +46,7 @@ struct trace_uprobe {
 	struct list_head		list;
 	struct ftrace_event_class	class;
 	struct ftrace_event_call	call;
+	bool				enabled;
 	struct uprobe_trace_consumer	*consumer;
 	struct trace_uprobe_filter	filter;
 	struct inode			*inode;
@@ -647,7 +648,7 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag)
 	struct uprobe_trace_consumer *utc;
 	int ret = 0;
 
-	if (tu->consumer)
+	if (tu->enabled)
 		return -EINTR;
 
 	utc = kzalloc(sizeof(struct uprobe_trace_consumer), GFP_KERNEL);
@@ -665,6 +666,8 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag)
 		tu->consumer = NULL;
 		tu->flags &= ~flag;
 		kfree(utc);
+	} else {
+		tu->enabled = true;
 	}
 
 	return ret;
@@ -672,11 +675,12 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag)
 
 static void probe_event_disable(struct trace_uprobe *tu, int flag)
 {
-	if (!tu->consumer)
+	if (!tu->enabled)
 		return;
 
 	uprobe_unregister(tu->inode, tu->offset, &tu->consumer->cons);
 	tu->flags &= ~flag;
+	tu->enabled = false;
 	kfree(tu->consumer);
 	tu->consumer = NULL;
 }
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] uprobes: Kill uprobe_trace_consumer, embed uprobe_consumer into trace_uprobe
  2013-01-28 18:24 [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups Oleg Nesterov
  2013-01-28 18:24 ` [PATCH 1/5] uprobes: Ensure inode != NULL in create_trace_uprobe() Oleg Nesterov
  2013-01-28 18:24 ` [PATCH 2/5] uprobes: Introduce trace_uprobe->enabled Oleg Nesterov
@ 2013-01-28 18:24 ` Oleg Nesterov
  2013-01-28 18:25 ` [PATCH 4/5] uprobes: Kill set_trace_uprobe_filter_func() Oleg Nesterov
  2013-01-28 18:25 ` [PATCH 5/5] uprobes: Kill trace_uprobe->enabled, introduce is_trace_uprobe_enabled() Oleg Nesterov
  4 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2013-01-28 18:24 UTC (permalink / raw)
  To: Ingo Molnar, Srikar Dronamraju, Steven Rostedt
  Cc: Anton Arapov, Frank Eigler, Josh Stone, Masami Hiramatsu,
	Suzuki K. Poulose, linux-kernel

trace_uprobe->consumer and "struct uprobe_trace_consumer" add the
unnecessary indirection and complicate the code for no reason.

This patch simply embeds uprobe_consumer into "struct trace_uprobe",
all other changes only fix the compilation errors.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/trace/trace_uprobe.c |   44 ++++++++++--------------------------------
 1 files changed, 11 insertions(+), 33 deletions(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index c430d01..6551b77 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -32,12 +32,6 @@
 /*
  * uprobe event core functions
  */
-struct trace_uprobe;
-struct uprobe_trace_consumer {
-	struct uprobe_consumer		cons;
-	struct trace_uprobe		*tu;
-};
-
 struct trace_uprobe_filter {
 	struct pid *tgid;
 };
@@ -47,7 +41,7 @@ struct trace_uprobe {
 	struct ftrace_event_class	class;
 	struct ftrace_event_call	call;
 	bool				enabled;
-	struct uprobe_trace_consumer	*consumer;
+	struct uprobe_consumer		consumer;
 	struct trace_uprobe_filter	filter;
 	struct inode			*inode;
 	char				*filename;
@@ -122,13 +116,13 @@ static bool trace_uprobe_filter_func(struct uprobe_consumer *uc,
 					enum uprobe_filter_ctx ctx,
 					struct mm_struct *mm)
 {
-	struct uprobe_trace_consumer *utc;
+	struct trace_uprobe *tu;
 	struct trace_uprobe_filter *filter;
 	struct task_struct *p, *t;
 	bool ret;
 
-	utc = container_of(uc, struct uprobe_trace_consumer, cons);
-	filter = &utc->tu->filter;
+	tu = container_of(uc, struct trace_uprobe, consumer);
+	filter = &tu->filter;
 
 	if (ctx == UPROBE_FILTER_MMAP)
 		return trace_uprobe_filter_current(filter);
@@ -645,30 +639,20 @@ partial:
 
 static int probe_event_enable(struct trace_uprobe *tu, int flag)
 {
-	struct uprobe_trace_consumer *utc;
 	int ret = 0;
 
 	if (tu->enabled)
 		return -EINTR;
 
-	utc = kzalloc(sizeof(struct uprobe_trace_consumer), GFP_KERNEL);
-	if (!utc)
-		return -EINTR;
-
-	set_trace_uprobe_filter_func(&utc->cons, &tu->filter);
-	utc->cons.handler = uprobe_dispatcher;
-	utc->tu = tu;
-	tu->consumer = utc;
+	set_trace_uprobe_filter_func(&tu->consumer, &tu->filter);
+	tu->consumer.handler = uprobe_dispatcher;
 	tu->flags |= flag;
 
-	ret = uprobe_register(tu->inode, tu->offset, &utc->cons);
-	if (ret) {
-		tu->consumer = NULL;
+	ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
+	if (ret)
 		tu->flags &= ~flag;
-		kfree(utc);
-	} else {
+	else
 		tu->enabled = true;
-	}
 
 	return ret;
 }
@@ -678,11 +662,9 @@ static void probe_event_disable(struct trace_uprobe *tu, int flag)
 	if (!tu->enabled)
 		return;
 
-	uprobe_unregister(tu->inode, tu->offset, &tu->consumer->cons);
+	uprobe_unregister(tu->inode, tu->offset, &tu->consumer);
 	tu->flags &= ~flag;
 	tu->enabled = false;
-	kfree(tu->consumer);
-	tu->consumer = NULL;
 }
 
 static int uprobe_event_define_fields(struct ftrace_event_call *event_call)
@@ -820,13 +802,9 @@ int trace_uprobe_register(struct ftrace_event_call *event, enum trace_reg type,
 
 static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
 {
-	struct uprobe_trace_consumer *utc;
 	struct trace_uprobe *tu;
 
-	utc = container_of(con, struct uprobe_trace_consumer, cons);
-	tu = utc->tu;
-	if (!tu || tu->consumer != utc)
-		return 0;
+	tu = container_of(con, struct trace_uprobe, consumer);
 
 	if (!trace_uprobe_filter_current(&tu->filter))
 		return UPROBE_HANDLER_REMOVE;
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] uprobes: Kill set_trace_uprobe_filter_func()
  2013-01-28 18:24 [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups Oleg Nesterov
                   ` (2 preceding siblings ...)
  2013-01-28 18:24 ` [PATCH 3/5] uprobes: Kill uprobe_trace_consumer, embed uprobe_consumer into trace_uprobe Oleg Nesterov
@ 2013-01-28 18:25 ` Oleg Nesterov
  2013-01-28 18:25 ` [PATCH 5/5] uprobes: Kill trace_uprobe->enabled, introduce is_trace_uprobe_enabled() Oleg Nesterov
  4 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2013-01-28 18:25 UTC (permalink / raw)
  To: Ingo Molnar, Srikar Dronamraju, Steven Rostedt
  Cc: Anton Arapov, Frank Eigler, Josh Stone, Masami Hiramatsu,
	Suzuki K. Poulose, linux-kernel

Now that uprobe_consumer is embedded into "struct trace_uprobe" we
can remove the ugly set_trace_uprobe_filter_func() and initialize
consumer->handler/filter at create_ time.

The patch looks complicated, but this is only because it moves
trace_uprobe_filter_func() up before init_trace_uprobe_filter().

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/trace/trace_uprobe.c |   97 ++++++++++++++++++++-----------------------
 1 files changed, 45 insertions(+), 52 deletions(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 6551b77..642e003 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -63,50 +63,6 @@ static void unregister_uprobe_event(struct trace_uprobe *tu);
 static DEFINE_MUTEX(uprobe_lock);
 static LIST_HEAD(uprobe_list);
 
-static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
-
-static int init_trace_uprobe_filter(struct trace_uprobe_filter *filter,
-					const char *arg)
-{
-	struct task_struct *p;
-	pid_t tgid;
-
-	if (!arg)
-		return 0;
-
-	if (kstrtouint(arg, 0, &tgid))
-		goto err;
-
-	filter->tgid = find_get_pid(tgid);
-	if (!filter->tgid)
-		goto err;
-
-	rcu_read_lock();
-	p = pid_task(filter->tgid, PIDTYPE_PID);
-	if (!p || !has_group_leader_pid(p) || (p->flags & PF_KTHREAD))
-		p = NULL;
-	rcu_read_unlock();
-
-	if (p)
-		return 0;
-err:
-	pr_info("Failed to find the process by pid=%s\n", arg);
-	/* free_trace_uprobe() will take care of ->tgid != NULL */
-	return -ESRCH;
-}
-
-static void free_trace_uprobe_filter(struct trace_uprobe_filter *filter)
-{
-	put_pid(filter->tgid);
-}
-
-static void probes_seq_show_filter(struct trace_uprobe_filter *filter,
-				struct seq_file *m)
-{
-	if (filter->tgid)
-		seq_printf(m, " pid=%d", pid_vnr(filter->tgid));
-}
-
 static bool trace_uprobe_filter_current(struct trace_uprobe_filter *filter)
 {
 	return !filter->tgid || filter->tgid == task_tgid(current);
@@ -144,13 +100,52 @@ static bool trace_uprobe_filter_func(struct uprobe_consumer *uc,
 	return ret;
 }
 
-static inline void set_trace_uprobe_filter_func(struct uprobe_consumer *uc,
-					struct trace_uprobe_filter *filter)
+static int init_trace_uprobe_filter(struct trace_uprobe *tu, const char *arg)
+{
+	struct task_struct *p;
+	pid_t tgid;
+
+	if (!arg)
+		return 0;
+
+	if (kstrtouint(arg, 0, &tgid))
+		goto err;
+
+	tu->filter.tgid = find_get_pid(tgid);
+	if (!tu->filter.tgid)
+		goto err;
+
+	rcu_read_lock();
+	p = pid_task(tu->filter.tgid, PIDTYPE_PID);
+	if (!p || !has_group_leader_pid(p) || (p->flags & PF_KTHREAD))
+		p = NULL;
+	rcu_read_unlock();
+
+	if (!p)
+		goto err;
+
+	tu->consumer.filter = trace_uprobe_filter_func;
+	return 0;
+err:
+	pr_info("Failed to find the process by pid=%s\n", arg);
+	/* free_trace_uprobe() will take care of ->tgid != NULL */
+	return -ESRCH;
+}
+
+static void free_trace_uprobe_filter(struct trace_uprobe *tu)
+{
+	put_pid(tu->filter.tgid);
+}
+
+static void probes_seq_show_filter(struct trace_uprobe_filter *filter,
+				struct seq_file *m)
 {
 	if (filter->tgid)
-		uc->filter = trace_uprobe_filter_func;
+		seq_printf(m, " pid=%d", pid_vnr(filter->tgid));
 }
 
+static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
+
 /*
  * Allocate new trace_uprobe and initialize it (including uprobes).
  */
@@ -179,6 +174,7 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs)
 		goto error;
 
 	INIT_LIST_HEAD(&tu->list);
+	tu->consumer.handler = uprobe_dispatcher;
 	return tu;
 
 error:
@@ -196,7 +192,7 @@ static void free_trace_uprobe(struct trace_uprobe *tu)
 		traceprobe_free_probe_arg(&tu->args[i]);
 
 	iput(tu->inode);
-	free_trace_uprobe_filter(&tu->filter);
+	free_trace_uprobe_filter(tu);
 	kfree(tu->call.class->system);
 	kfree(tu->call.name);
 	kfree(tu->filename);
@@ -397,7 +393,7 @@ static int create_trace_uprobe(int argc, char **argv)
 		goto error;
 	}
 
-	ret = init_trace_uprobe_filter(&tu->filter, filter_arg);
+	ret = init_trace_uprobe_filter(tu, filter_arg);
 	if (ret)
 		goto error;
 
@@ -644,10 +640,7 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag)
 	if (tu->enabled)
 		return -EINTR;
 
-	set_trace_uprobe_filter_func(&tu->consumer, &tu->filter);
-	tu->consumer.handler = uprobe_dispatcher;
 	tu->flags |= flag;
-
 	ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
 	if (ret)
 		tu->flags &= ~flag;
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] uprobes: Kill trace_uprobe->enabled, introduce is_trace_uprobe_enabled()
  2013-01-28 18:24 [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups Oleg Nesterov
                   ` (3 preceding siblings ...)
  2013-01-28 18:25 ` [PATCH 4/5] uprobes: Kill set_trace_uprobe_filter_func() Oleg Nesterov
@ 2013-01-28 18:25 ` Oleg Nesterov
  4 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2013-01-28 18:25 UTC (permalink / raw)
  To: Ingo Molnar, Srikar Dronamraju, Steven Rostedt
  Cc: Anton Arapov, Frank Eigler, Josh Stone, Masami Hiramatsu,
	Suzuki K. Poulose, linux-kernel

Finally kill trace_uprobe->enabled and add is_trace_uprobe_enabled()
which can rely on TP_FLAG_TRACE/TP_FLAG_PROFILE bits we set/clear
anyway.

Note that we could do this from the very beginning, ->enabled was
never strictly needed. But I'd prefer to do this as a last change
so that it can be dropped if the reviewers do not like the (ab)use
of tu->flags.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/trace/trace_uprobe.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 642e003..1e1633c 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -40,7 +40,6 @@ struct trace_uprobe {
 	struct list_head		list;
 	struct ftrace_event_class	class;
 	struct ftrace_event_call	call;
-	bool				enabled;
 	struct uprobe_consumer		consumer;
 	struct trace_uprobe_filter	filter;
 	struct inode			*inode;
@@ -633,31 +632,33 @@ partial:
 	return TRACE_TYPE_PARTIAL_LINE;
 }
 
+static inline bool is_trace_uprobe_enabled(struct trace_uprobe *tu)
+{
+	return tu->flags & (TP_FLAG_TRACE | TP_FLAG_PROFILE);
+}
+
 static int probe_event_enable(struct trace_uprobe *tu, int flag)
 {
 	int ret = 0;
 
-	if (tu->enabled)
+	if (is_trace_uprobe_enabled(tu))
 		return -EINTR;
 
 	tu->flags |= flag;
 	ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
 	if (ret)
 		tu->flags &= ~flag;
-	else
-		tu->enabled = true;
 
 	return ret;
 }
 
 static void probe_event_disable(struct trace_uprobe *tu, int flag)
 {
-	if (!tu->enabled)
+	if (!is_trace_uprobe_enabled(tu))
 		return;
 
 	uprobe_unregister(tu->inode, tu->offset, &tu->consumer);
 	tu->flags &= ~flag;
-	tu->enabled = false;
 }
 
 static int uprobe_event_define_fields(struct ftrace_event_call *event_call)
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-01-28 18:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-28 18:24 [PATCH 0/5] uprobes: kill uprobe_trace_consumer and other cleanups Oleg Nesterov
2013-01-28 18:24 ` [PATCH 1/5] uprobes: Ensure inode != NULL in create_trace_uprobe() Oleg Nesterov
2013-01-28 18:24 ` [PATCH 2/5] uprobes: Introduce trace_uprobe->enabled Oleg Nesterov
2013-01-28 18:24 ` [PATCH 3/5] uprobes: Kill uprobe_trace_consumer, embed uprobe_consumer into trace_uprobe Oleg Nesterov
2013-01-28 18:25 ` [PATCH 4/5] uprobes: Kill set_trace_uprobe_filter_func() Oleg Nesterov
2013-01-28 18:25 ` [PATCH 5/5] uprobes: Kill trace_uprobe->enabled, introduce is_trace_uprobe_enabled() Oleg Nesterov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox