From: Oleg Nesterov <oleg@redhat.com>
To: Ingo Molnar <mingo@elte.hu>,
Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
Steven Rostedt <rostedt@goodmis.org>
Cc: Anton Arapov <anton@redhat.com>, Frank Eigler <fche@redhat.com>,
Josh Stone <jistone@redhat.com>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
"Suzuki K. Poulose" <suzuki@in.ibm.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 3/4] uprobes: Teach tracing/uprobe_events to accept pid=TGID argument
Date: Sun, 27 Jan 2013 20:48:40 +0100 [thread overview]
Message-ID: <20130127194840.GA25405@redhat.com> (raw)
In-Reply-To: <20130127194814.GA25377@redhat.com>
A separate change to simplify the review.
With this patch create_trace_uprobe() parses the new pid=TGID argument
and stores the found "struct pid *" in "struct trace_uprobe" along with
inode/offset.
However, to simplify the potential extensions, we add the new structure
to hold this pid, and the set of its methods. This way we can, say, change
this code to accept the list of pid's without touching the non-filtering
code again.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
kernel/trace/trace_uprobe.c | 66 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 94d4ea2..f7a2dcb 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -23,6 +23,7 @@
#include <linux/uprobes.h>
#include <linux/namei.h>
#include <linux/string.h>
+#include <linux/pid.h>
#include "trace_probe.h"
@@ -37,11 +38,16 @@ struct uprobe_trace_consumer {
struct trace_uprobe *tu;
};
+struct trace_uprobe_filter {
+ struct pid *tgid;
+};
+
struct trace_uprobe {
struct list_head list;
struct ftrace_event_class class;
struct ftrace_event_call call;
struct uprobe_trace_consumer *consumer;
+ struct trace_uprobe_filter filter;
struct inode *inode;
char *filename;
unsigned long offset;
@@ -64,6 +70,48 @@ 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));
+}
+
/*
* Allocate new trace_uprobe and initialize it (including uprobes).
*/
@@ -111,6 +159,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);
kfree(tu->call.class->system);
kfree(tu->call.name);
kfree(tu->filename);
@@ -167,7 +216,7 @@ end:
/*
* Argument syntax:
- * - Add uprobe: p[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS]
+ * - Add uprobe: p[:[GRP/]EVENT] PATH:OFFSET [pid=TGID] [FETCHARGS]
*
* - Remove uprobe: -:[GRP/]EVENT
*/
@@ -176,6 +225,7 @@ static int create_trace_uprobe(int argc, char **argv)
struct trace_uprobe *tu;
struct inode *inode;
char *arg, *event, *group, *filename;
+ char *filter_arg;
char buf[MAX_EVENT_NAME_LEN];
struct path path;
unsigned long offset;
@@ -265,6 +315,13 @@ static int create_trace_uprobe(int argc, char **argv)
argc -= 2;
argv += 2;
+ filter_arg = NULL;
+ if (argc && strncmp(argv[0], "pid=", 4) == 0) {
+ filter_arg = argv[0] + 4;
+ argc--;
+ argv++;
+ }
+
/* setup a probe */
if (!event) {
char *tail;
@@ -301,8 +358,11 @@ static int create_trace_uprobe(int argc, char **argv)
goto error;
}
+ ret = init_trace_uprobe_filter(&tu->filter, filter_arg);
+ if (ret)
+ goto error;
+
/* parse arguments */
- ret = 0;
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
/* Increment count for freeing args in error case */
tu->nr_args++;
@@ -402,6 +462,8 @@ static int probes_seq_show(struct seq_file *m, void *v)
seq_printf(m, "p:%s/%s", tu->call.class->system, tu->call.name);
seq_printf(m, " %s:0x%p", tu->filename, (void *)tu->offset);
+ probes_seq_show_filter(&tu->filter, m);
+
for (i = 0; i < tu->nr_args; i++)
seq_printf(m, " %s=%s", tu->args[i].name, tu->args[i].comm);
--
1.5.5.1
next prev parent reply other threads:[~2013-01-27 19:50 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-27 19:48 [PATCH 0/4] uprobes: Teach debug/tracing/uprobe_events to do the filtering Oleg Nesterov
2013-01-27 19:48 ` [PATCH 1/4] uprobes: Fix dentry/mount leak in create_trace_uprobe() Oleg Nesterov
2013-01-28 12:08 ` Srikar Dronamraju
2013-01-27 19:48 ` [PATCH 2/4] uprobes: Fully initialize uprobe_trace_consumer before uprobe_register() Oleg Nesterov
2013-01-28 12:09 ` Srikar Dronamraju
2013-01-27 19:48 ` Oleg Nesterov [this message]
2013-01-27 19:48 ` [PATCH 4/4] uprobes: Teach uprobe_trace_consumer to support the pre-filtering Oleg Nesterov
2013-01-31 17:04 ` [PATCH 0/4] uprobes: Teach debug/tracing/uprobe_events to do the filtering Oleg Nesterov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130127194840.GA25405@redhat.com \
--to=oleg@redhat.com \
--cc=anton@redhat.com \
--cc=fche@redhat.com \
--cc=jistone@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@elte.hu \
--cc=rostedt@goodmis.org \
--cc=srikar@linux.vnet.ibm.com \
--cc=suzuki@in.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox