* [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup
@ 2015-03-30 20:35 David Ahern
2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: David Ahern @ 2015-03-30 20:35 UTC (permalink / raw)
To: acme; +Cc: linux-kernel, David Ahern, Don Zickus, Joe Mario, Jiri Olsa
Rather than parsing /proc/pid/status file one line at a time, read
it into a buffer in one shot and search for all strings in one pass.
tgid conversion also simplified -- removing the isspace walk. As
noted by Arnaldo those are not needed for atoi == strtol calls.
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Joe Mario <jmario@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
---
v2:
- removed the isspace checks on tgid string
tools/perf/util/event.c | 72 ++++++++++++++++++++++++++++++-------------------
1 file changed, 44 insertions(+), 28 deletions(-)
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d5efa5092ce6..023dd3548a94 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -49,48 +49,64 @@ static struct perf_sample synth_sample = {
.period = 1,
};
+/*
+ * Assumes that the first 4095 bytes of /proc/pid/stat contains
+ * the comm and tgid.
+ */
static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len)
{
char filename[PATH_MAX];
- char bf[BUFSIZ];
- FILE *fp;
- size_t size = 0;
+ char bf[4096];
+ int fd;
+ size_t size = 0, n;
pid_t tgid = -1;
+ char *nl, *name, *tgids;
snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
- fp = fopen(filename, "r");
- if (fp == NULL) {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
pr_debug("couldn't open %s\n", filename);
return 0;
}
- while (!comm[0] || (tgid < 0)) {
- if (fgets(bf, sizeof(bf), fp) == NULL) {
- pr_warning("couldn't get COMM and pgid, malformed %s\n",
- filename);
- break;
- }
+ n = read(fd, bf, sizeof(bf) - 1);
+ close(fd);
+ if (n <= 0) {
+ pr_warning("Couldn't get COMM and tgid for pid %d\n",
+ pid);
+ return -1;
+ }
+ bf[n] = '\0';
- if (memcmp(bf, "Name:", 5) == 0) {
- char *name = bf + 5;
- while (*name && isspace(*name))
- ++name;
- size = strlen(name) - 1;
- if (size >= len)
- size = len - 1;
- memcpy(comm, name, size);
- comm[size] = '\0';
-
- } else if (memcmp(bf, "Tgid:", 5) == 0) {
- char *tgids = bf + 5;
- while (*tgids && isspace(*tgids))
- ++tgids;
- tgid = atoi(tgids);
- }
+ name = strstr(bf, "Name:");
+ tgids = strstr(bf, "Tgid:");
+
+ if (name) {
+ name += 5; /* strlen("Name:") */
+
+ while (*name && isspace(*name))
+ ++name;
+
+ nl = strchr(name, '\n');
+ if (nl)
+ *nl = '\0';
+
+ size = strlen(name);
+ if (size >= len)
+ size = len - 1;
+ memcpy(comm, name, size);
+ comm[size] = '\0';
+ } else {
+ pr_debug("Name: string not found for pid %d\n", pid);
}
- fclose(fp);
+ if (tgids) {
+ tgids += 5; /* strlen("Tgid:") */
+ tgid = atoi(tgids);
+ } else {
+ pr_debug("Tgid: string not found for pid %d\n", pid);
+ }
return tgid;
}
--
2.2.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events 2015-03-30 20:35 [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup David Ahern @ 2015-03-30 20:35 ` David Ahern 2015-03-31 14:10 ` Jiri Olsa ` (3 more replies) 2015-03-31 14:35 ` [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup Jiri Olsa ` (2 subsequent siblings) 3 siblings, 4 replies; 11+ messages in thread From: David Ahern @ 2015-03-30 20:35 UTC (permalink / raw) To: acme; +Cc: linux-kernel, David Ahern, Don Zickus, Joe Mario, Jiri Olsa 363b785f38 added synthesized fork events and set a thread's parent id to itself. Since we are already processing /proc/<pid>/status the ppid can be determined properly. Make it so. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Don Zickus <dzickus@redhat.com> Cc: Joe Mario <jmario@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> --- v3 - removed isspace and newline checks; added brackets per Arnaldo's comments v2: - removed changes to function signature for perf_event__synthesize_comm as noted by Jiri tools/perf/util/event.c | 83 +++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 023dd3548a94..5516236df6ab 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -51,29 +51,32 @@ static struct perf_sample synth_sample = { /* * Assumes that the first 4095 bytes of /proc/pid/stat contains - * the comm and tgid. + * the comm, tgid and ppid. */ -static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, + pid_t *tgid, pid_t *ppid) { char filename[PATH_MAX]; char bf[4096]; int fd; size_t size = 0, n; - pid_t tgid = -1; - char *nl, *name, *tgids; + char *nl, *name, *tgids, *ppids; + + *tgid = -1; + *ppid = -1; snprintf(filename, sizeof(filename), "/proc/%d/status", pid); fd = open(filename, O_RDONLY); if (fd < 0) { pr_debug("couldn't open %s\n", filename); - return 0; + return -1; } n = read(fd, bf, sizeof(bf) - 1); close(fd); if (n <= 0) { - pr_warning("Couldn't get COMM and tgid for pid %d\n", + pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", pid); return -1; } @@ -81,6 +84,7 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) name = strstr(bf, "Name:"); tgids = strstr(bf, "Tgid:"); + ppids = strstr(bf, "PPid:"); if (name) { name += 5; /* strlen("Name:") */ @@ -103,32 +107,45 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) if (tgids) { tgids += 5; /* strlen("Tgid:") */ - tgid = atoi(tgids); + *tgid = atoi(tgids); } else { pr_debug("Tgid: string not found for pid %d\n", pid); } - return tgid; + if (ppids) { + ppids += 5; /* strlen("PPid:") */ + *ppid = atoi(ppids); + } else { + pr_debug("PPid: string not found for pid %d\n", pid); + } + + return 0; } -static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, - struct machine *machine) +static int perf_event__prepare_comm(union perf_event *event, pid_t pid, + struct machine *machine, + pid_t *tgid, pid_t *ppid) { size_t size; - pid_t tgid; + + *ppid = -1; memset(&event->comm, 0, sizeof(event->comm)); - if (machine__is_host(machine)) - tgid = perf_event__get_comm_tgid(pid, event->comm.comm, - sizeof(event->comm.comm)); - else - tgid = machine->pid; + if (machine__is_host(machine)) { + if (perf_event__get_comm_ids(pid, event->comm.comm, + sizeof(event->comm.comm), + tgid, ppid) != 0) { + return -1; + } + } else { + *tgid = machine->pid; + } - if (tgid < 0) - goto out; + if (*tgid < 0) + return -1; - event->comm.pid = tgid; + event->comm.pid = *tgid; event->comm.header.type = PERF_RECORD_COMM; size = strlen(event->comm.comm) + 1; @@ -138,8 +155,8 @@ static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, (sizeof(event->comm.comm) - size) + machine->id_hdr_size); event->comm.tid = pid; -out: - return tgid; + + return 0; } static pid_t perf_event__synthesize_comm(struct perf_tool *tool, @@ -147,27 +164,27 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine) { - pid_t tgid = perf_event__prepare_comm(event, pid, machine); + pid_t tgid, ppid; - if (tgid == -1) - goto out; + if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0) + return -1; if (process(tool, event, &synth_sample, machine) != 0) return -1; -out: return tgid; } static int perf_event__synthesize_fork(struct perf_tool *tool, - union perf_event *event, pid_t pid, - pid_t tgid, perf_event__handler_t process, + union perf_event *event, + pid_t pid, pid_t tgid, pid_t ppid, + perf_event__handler_t process, struct machine *machine) { memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); - event->fork.ppid = tgid; - event->fork.ptid = tgid; + event->fork.ppid = ppid; + event->fork.ptid = ppid; event->fork.pid = tgid; event->fork.tid = pid; event->fork.header.type = PERF_RECORD_FORK; @@ -359,7 +376,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, char filename[PATH_MAX]; DIR *tasks; struct dirent dirent, *next; - pid_t tgid; + pid_t tgid, ppid; /* special case: only send one comm event using passed in pid */ if (!full) { @@ -394,12 +411,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, if (*end) continue; - tgid = perf_event__prepare_comm(comm_event, _pid, machine); - if (tgid == -1) + if (perf_event__prepare_comm(comm_event, _pid, machine, + &tgid, &ppid) != 0) return -1; if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, - process, machine) < 0) + ppid, process, machine) < 0) return -1; /* * Send the prepared comm event -- 2.2.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern @ 2015-03-31 14:10 ` Jiri Olsa 2015-03-31 14:17 ` Jiri Olsa 2015-03-31 14:35 ` Jiri Olsa ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Jiri Olsa @ 2015-03-31 14:10 UTC (permalink / raw) To: David Ahern; +Cc: acme, linux-kernel, Don Zickus, Joe Mario On Mon, Mar 30, 2015 at 02:35:58PM -0600, David Ahern wrote: > 363b785f38 added synthesized fork events and set a thread's parent id > to itself. Since we are already processing /proc/<pid>/status the ppid > can be determined properly. Make it so. > > Signed-off-by: David Ahern <dsahern@gmail.com> > Cc: Don Zickus <dzickus@redhat.com> > Cc: Joe Mario <jmario@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> > --- > v3 > - removed isspace and newline checks; added brackets per Arnaldo's comments > > v2: > - removed changes to function signature for perf_event__synthesize_comm as > noted by Jiri > > tools/perf/util/event.c | 83 +++++++++++++++++++++++++++++-------------------- > 1 file changed, 50 insertions(+), 33 deletions(-) > > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > index 023dd3548a94..5516236df6ab 100644 > --- a/tools/perf/util/event.c > +++ b/tools/perf/util/event.c > @@ -51,29 +51,32 @@ static struct perf_sample synth_sample = { > > /* > * Assumes that the first 4095 bytes of /proc/pid/stat contains > - * the comm and tgid. > + * the comm, tgid and ppid. > */ > -static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, > + pid_t *tgid, pid_t *ppid) > { > char filename[PATH_MAX]; > char bf[4096]; > int fd; > size_t size = 0, n; > - pid_t tgid = -1; > - char *nl, *name, *tgids; > + char *nl, *name, *tgids, *ppids; > + > + *tgid = -1; > + *ppid = -1; > > snprintf(filename, sizeof(filename), "/proc/%d/status", pid); > > fd = open(filename, O_RDONLY); > if (fd < 0) { > pr_debug("couldn't open %s\n", filename); > - return 0; > + return -1; hum, missed this one in previous version.. why did not we fail before? jirka ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events 2015-03-31 14:10 ` Jiri Olsa @ 2015-03-31 14:17 ` Jiri Olsa 0 siblings, 0 replies; 11+ messages in thread From: Jiri Olsa @ 2015-03-31 14:17 UTC (permalink / raw) To: David Ahern; +Cc: acme, linux-kernel, Don Zickus, Joe Mario On Tue, Mar 31, 2015 at 04:10:26PM +0200, Jiri Olsa wrote: > On Mon, Mar 30, 2015 at 02:35:58PM -0600, David Ahern wrote: > > 363b785f38 added synthesized fork events and set a thread's parent id > > to itself. Since we are already processing /proc/<pid>/status the ppid > > can be determined properly. Make it so. > > > > Signed-off-by: David Ahern <dsahern@gmail.com> > > Cc: Don Zickus <dzickus@redhat.com> > > Cc: Joe Mario <jmario@redhat.com> > > Cc: Jiri Olsa <jolsa@redhat.com> > > --- > > v3 > > - removed isspace and newline checks; added brackets per Arnaldo's comments > > > > v2: > > - removed changes to function signature for perf_event__synthesize_comm as > > noted by Jiri > > > > tools/perf/util/event.c | 83 +++++++++++++++++++++++++++++-------------------- > > 1 file changed, 50 insertions(+), 33 deletions(-) > > > > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > > index 023dd3548a94..5516236df6ab 100644 > > --- a/tools/perf/util/event.c > > +++ b/tools/perf/util/event.c > > @@ -51,29 +51,32 @@ static struct perf_sample synth_sample = { > > > > /* > > * Assumes that the first 4095 bytes of /proc/pid/stat contains > > - * the comm and tgid. > > + * the comm, tgid and ppid. > > */ > > -static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > > +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, > > + pid_t *tgid, pid_t *ppid) > > { > > char filename[PATH_MAX]; > > char bf[4096]; > > int fd; > > size_t size = 0, n; > > - pid_t tgid = -1; > > - char *nl, *name, *tgids; > > + char *nl, *name, *tgids, *ppids; > > + > > + *tgid = -1; > > + *ppid = -1; > > > > snprintf(filename, sizeof(filename), "/proc/%d/status", pid); > > > > fd = open(filename, O_RDONLY); > > if (fd < 0) { > > pr_debug("couldn't open %s\n", filename); > > - return 0; > > + return -1; > > hum, missed this one in previous version.. why did not we fail before? sigh, it was the tgid before, now it's err.. ;-) ook jirka ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern 2015-03-31 14:10 ` Jiri Olsa @ 2015-03-31 14:35 ` Jiri Olsa 2015-03-31 16:23 ` Don Zickus 2015-04-02 12:23 ` [tip:perf/core] perf tools: " tip-bot for David Ahern 3 siblings, 0 replies; 11+ messages in thread From: Jiri Olsa @ 2015-03-31 14:35 UTC (permalink / raw) To: David Ahern; +Cc: acme, linux-kernel, Don Zickus, Joe Mario On Mon, Mar 30, 2015 at 02:35:58PM -0600, David Ahern wrote: > 363b785f38 added synthesized fork events and set a thread's parent id > to itself. Since we are already processing /proc/<pid>/status the ppid > can be determined properly. Make it so. > > Signed-off-by: David Ahern <dsahern@gmail.com> > Cc: Don Zickus <dzickus@redhat.com> > Cc: Joe Mario <jmario@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> thanks, jirka ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern 2015-03-31 14:10 ` Jiri Olsa 2015-03-31 14:35 ` Jiri Olsa @ 2015-03-31 16:23 ` Don Zickus 2015-04-02 12:23 ` [tip:perf/core] perf tools: " tip-bot for David Ahern 3 siblings, 0 replies; 11+ messages in thread From: Don Zickus @ 2015-03-31 16:23 UTC (permalink / raw) To: David Ahern; +Cc: acme, linux-kernel, Joe Mario, Jiri Olsa On Mon, Mar 30, 2015 at 02:35:58PM -0600, David Ahern wrote: > 363b785f38 added synthesized fork events and set a thread's parent id > to itself. Since we are already processing /proc/<pid>/status the ppid > can be determined properly. Make it so. Acked-by: Don Zickus <dzickus@redhat.com> > > Signed-off-by: David Ahern <dsahern@gmail.com> > Cc: Don Zickus <dzickus@redhat.com> > Cc: Joe Mario <jmario@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> > --- > v3 > - removed isspace and newline checks; added brackets per Arnaldo's comments > > v2: > - removed changes to function signature for perf_event__synthesize_comm as > noted by Jiri > > tools/perf/util/event.c | 83 +++++++++++++++++++++++++++++-------------------- > 1 file changed, 50 insertions(+), 33 deletions(-) > > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > index 023dd3548a94..5516236df6ab 100644 > --- a/tools/perf/util/event.c > +++ b/tools/perf/util/event.c > @@ -51,29 +51,32 @@ static struct perf_sample synth_sample = { > > /* > * Assumes that the first 4095 bytes of /proc/pid/stat contains > - * the comm and tgid. > + * the comm, tgid and ppid. > */ > -static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, > + pid_t *tgid, pid_t *ppid) > { > char filename[PATH_MAX]; > char bf[4096]; > int fd; > size_t size = 0, n; > - pid_t tgid = -1; > - char *nl, *name, *tgids; > + char *nl, *name, *tgids, *ppids; > + > + *tgid = -1; > + *ppid = -1; > > snprintf(filename, sizeof(filename), "/proc/%d/status", pid); > > fd = open(filename, O_RDONLY); > if (fd < 0) { > pr_debug("couldn't open %s\n", filename); > - return 0; > + return -1; > } > > n = read(fd, bf, sizeof(bf) - 1); > close(fd); > if (n <= 0) { > - pr_warning("Couldn't get COMM and tgid for pid %d\n", > + pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", > pid); > return -1; > } > @@ -81,6 +84,7 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > > name = strstr(bf, "Name:"); > tgids = strstr(bf, "Tgid:"); > + ppids = strstr(bf, "PPid:"); > > if (name) { > name += 5; /* strlen("Name:") */ > @@ -103,32 +107,45 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > > if (tgids) { > tgids += 5; /* strlen("Tgid:") */ > - tgid = atoi(tgids); > + *tgid = atoi(tgids); > } else { > pr_debug("Tgid: string not found for pid %d\n", pid); > } > > - return tgid; > + if (ppids) { > + ppids += 5; /* strlen("PPid:") */ > + *ppid = atoi(ppids); > + } else { > + pr_debug("PPid: string not found for pid %d\n", pid); > + } > + > + return 0; > } > > -static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, > - struct machine *machine) > +static int perf_event__prepare_comm(union perf_event *event, pid_t pid, > + struct machine *machine, > + pid_t *tgid, pid_t *ppid) > { > size_t size; > - pid_t tgid; > + > + *ppid = -1; > > memset(&event->comm, 0, sizeof(event->comm)); > > - if (machine__is_host(machine)) > - tgid = perf_event__get_comm_tgid(pid, event->comm.comm, > - sizeof(event->comm.comm)); > - else > - tgid = machine->pid; > + if (machine__is_host(machine)) { > + if (perf_event__get_comm_ids(pid, event->comm.comm, > + sizeof(event->comm.comm), > + tgid, ppid) != 0) { > + return -1; > + } > + } else { > + *tgid = machine->pid; > + } > > - if (tgid < 0) > - goto out; > + if (*tgid < 0) > + return -1; > > - event->comm.pid = tgid; > + event->comm.pid = *tgid; > event->comm.header.type = PERF_RECORD_COMM; > > size = strlen(event->comm.comm) + 1; > @@ -138,8 +155,8 @@ static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, > (sizeof(event->comm.comm) - size) + > machine->id_hdr_size); > event->comm.tid = pid; > -out: > - return tgid; > + > + return 0; > } > > static pid_t perf_event__synthesize_comm(struct perf_tool *tool, > @@ -147,27 +164,27 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, > perf_event__handler_t process, > struct machine *machine) > { > - pid_t tgid = perf_event__prepare_comm(event, pid, machine); > + pid_t tgid, ppid; > > - if (tgid == -1) > - goto out; > + if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0) > + return -1; > > if (process(tool, event, &synth_sample, machine) != 0) > return -1; > > -out: > return tgid; > } > > static int perf_event__synthesize_fork(struct perf_tool *tool, > - union perf_event *event, pid_t pid, > - pid_t tgid, perf_event__handler_t process, > + union perf_event *event, > + pid_t pid, pid_t tgid, pid_t ppid, > + perf_event__handler_t process, > struct machine *machine) > { > memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); > > - event->fork.ppid = tgid; > - event->fork.ptid = tgid; > + event->fork.ppid = ppid; > + event->fork.ptid = ppid; > event->fork.pid = tgid; > event->fork.tid = pid; > event->fork.header.type = PERF_RECORD_FORK; > @@ -359,7 +376,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, > char filename[PATH_MAX]; > DIR *tasks; > struct dirent dirent, *next; > - pid_t tgid; > + pid_t tgid, ppid; > > /* special case: only send one comm event using passed in pid */ > if (!full) { > @@ -394,12 +411,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, > if (*end) > continue; > > - tgid = perf_event__prepare_comm(comm_event, _pid, machine); > - if (tgid == -1) > + if (perf_event__prepare_comm(comm_event, _pid, machine, > + &tgid, &ppid) != 0) > return -1; > > if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, > - process, machine) < 0) > + ppid, process, machine) < 0) > return -1; > /* > * Send the prepared comm event > -- > 2.2.1 > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [tip:perf/core] perf tools: Fix ppid for synthesized fork events 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern ` (2 preceding siblings ...) 2015-03-31 16:23 ` Don Zickus @ 2015-04-02 12:23 ` tip-bot for David Ahern 3 siblings, 0 replies; 11+ messages in thread From: tip-bot for David Ahern @ 2015-04-02 12:23 UTC (permalink / raw) To: linux-tip-commits Cc: mingo, dzickus, jmario, jolsa, hpa, linux-kernel, acme, dsahern, tglx Commit-ID: ca6c41c59b964d362823e80442e9e32c31106b29 Gitweb: http://git.kernel.org/tip/ca6c41c59b964d362823e80442e9e32c31106b29 Author: David Ahern <dsahern@gmail.com> AuthorDate: Mon, 30 Mar 2015 14:35:58 -0600 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Tue, 31 Mar 2015 17:52:30 -0300 perf tools: Fix ppid for synthesized fork events 363b785f38 added synthesized fork events and set a thread's parent id to itself. Since we are already processing /proc/<pid>/status the ppid can be determined properly. Make it so. Signed-off-by: David Ahern <dsahern@gmail.com> Acked-by: Don Zickus <dzickus@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Joe Mario <jmario@redhat.com> Link: http://lkml.kernel.org/r/1427747758-18510-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/event.c | 83 +++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 023dd35..5516236 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -51,29 +51,32 @@ static struct perf_sample synth_sample = { /* * Assumes that the first 4095 bytes of /proc/pid/stat contains - * the comm and tgid. + * the comm, tgid and ppid. */ -static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, + pid_t *tgid, pid_t *ppid) { char filename[PATH_MAX]; char bf[4096]; int fd; size_t size = 0, n; - pid_t tgid = -1; - char *nl, *name, *tgids; + char *nl, *name, *tgids, *ppids; + + *tgid = -1; + *ppid = -1; snprintf(filename, sizeof(filename), "/proc/%d/status", pid); fd = open(filename, O_RDONLY); if (fd < 0) { pr_debug("couldn't open %s\n", filename); - return 0; + return -1; } n = read(fd, bf, sizeof(bf) - 1); close(fd); if (n <= 0) { - pr_warning("Couldn't get COMM and tgid for pid %d\n", + pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", pid); return -1; } @@ -81,6 +84,7 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) name = strstr(bf, "Name:"); tgids = strstr(bf, "Tgid:"); + ppids = strstr(bf, "PPid:"); if (name) { name += 5; /* strlen("Name:") */ @@ -103,32 +107,45 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) if (tgids) { tgids += 5; /* strlen("Tgid:") */ - tgid = atoi(tgids); + *tgid = atoi(tgids); } else { pr_debug("Tgid: string not found for pid %d\n", pid); } - return tgid; + if (ppids) { + ppids += 5; /* strlen("PPid:") */ + *ppid = atoi(ppids); + } else { + pr_debug("PPid: string not found for pid %d\n", pid); + } + + return 0; } -static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, - struct machine *machine) +static int perf_event__prepare_comm(union perf_event *event, pid_t pid, + struct machine *machine, + pid_t *tgid, pid_t *ppid) { size_t size; - pid_t tgid; + + *ppid = -1; memset(&event->comm, 0, sizeof(event->comm)); - if (machine__is_host(machine)) - tgid = perf_event__get_comm_tgid(pid, event->comm.comm, - sizeof(event->comm.comm)); - else - tgid = machine->pid; + if (machine__is_host(machine)) { + if (perf_event__get_comm_ids(pid, event->comm.comm, + sizeof(event->comm.comm), + tgid, ppid) != 0) { + return -1; + } + } else { + *tgid = machine->pid; + } - if (tgid < 0) - goto out; + if (*tgid < 0) + return -1; - event->comm.pid = tgid; + event->comm.pid = *tgid; event->comm.header.type = PERF_RECORD_COMM; size = strlen(event->comm.comm) + 1; @@ -138,8 +155,8 @@ static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, (sizeof(event->comm.comm) - size) + machine->id_hdr_size); event->comm.tid = pid; -out: - return tgid; + + return 0; } static pid_t perf_event__synthesize_comm(struct perf_tool *tool, @@ -147,27 +164,27 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine) { - pid_t tgid = perf_event__prepare_comm(event, pid, machine); + pid_t tgid, ppid; - if (tgid == -1) - goto out; + if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0) + return -1; if (process(tool, event, &synth_sample, machine) != 0) return -1; -out: return tgid; } static int perf_event__synthesize_fork(struct perf_tool *tool, - union perf_event *event, pid_t pid, - pid_t tgid, perf_event__handler_t process, + union perf_event *event, + pid_t pid, pid_t tgid, pid_t ppid, + perf_event__handler_t process, struct machine *machine) { memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); - event->fork.ppid = tgid; - event->fork.ptid = tgid; + event->fork.ppid = ppid; + event->fork.ptid = ppid; event->fork.pid = tgid; event->fork.tid = pid; event->fork.header.type = PERF_RECORD_FORK; @@ -359,7 +376,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, char filename[PATH_MAX]; DIR *tasks; struct dirent dirent, *next; - pid_t tgid; + pid_t tgid, ppid; /* special case: only send one comm event using passed in pid */ if (!full) { @@ -394,12 +411,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, if (*end) continue; - tgid = perf_event__prepare_comm(comm_event, _pid, machine); - if (tgid == -1) + if (perf_event__prepare_comm(comm_event, _pid, machine, + &tgid, &ppid) != 0) return -1; if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, - process, machine) < 0) + ppid, process, machine) < 0) return -1; /* * Send the prepared comm event ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup 2015-03-30 20:35 [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup David Ahern 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern @ 2015-03-31 14:35 ` Jiri Olsa 2015-03-31 15:55 ` Arnaldo Carvalho de Melo 2015-03-31 16:22 ` Don Zickus 2015-04-02 12:23 ` [tip:perf/core] perf tools: " tip-bot for David Ahern 3 siblings, 1 reply; 11+ messages in thread From: Jiri Olsa @ 2015-03-31 14:35 UTC (permalink / raw) To: David Ahern; +Cc: acme, linux-kernel, Don Zickus, Joe Mario On Mon, Mar 30, 2015 at 02:35:57PM -0600, David Ahern wrote: > Rather than parsing /proc/pid/status file one line at a time, read > it into a buffer in one shot and search for all strings in one pass. > > tgid conversion also simplified -- removing the isspace walk. As > noted by Arnaldo those are not needed for atoi == strtol calls. > > Signed-off-by: David Ahern <dsahern@gmail.com> > Cc: Don Zickus <dzickus@redhat.com> > Cc: Joe Mario <jmario@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> thanks, jirka ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup 2015-03-31 14:35 ` [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup Jiri Olsa @ 2015-03-31 15:55 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 11+ messages in thread From: Arnaldo Carvalho de Melo @ 2015-03-31 15:55 UTC (permalink / raw) To: Jiri Olsa; +Cc: David Ahern, linux-kernel, Don Zickus, Joe Mario Em Tue, Mar 31, 2015 at 04:35:46PM +0200, Jiri Olsa escreveu: > On Mon, Mar 30, 2015 at 02:35:57PM -0600, David Ahern wrote: > > Rather than parsing /proc/pid/status file one line at a time, read > > it into a buffer in one shot and search for all strings in one pass. > > > > tgid conversion also simplified -- removing the isspace walk. As > > noted by Arnaldo those are not needed for atoi == strtol calls. > > > > Signed-off-by: David Ahern <dsahern@gmail.com> > > Cc: Don Zickus <dzickus@redhat.com> > > Cc: Joe Mario <jmario@redhat.com> > > Cc: Jiri Olsa <jolsa@redhat.com> > > Acked-by: Jiri Olsa <jolsa@kernel.org> Thanks, applied both, with Jiri's acks. - Arnaldo ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup 2015-03-30 20:35 [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup David Ahern 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern 2015-03-31 14:35 ` [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup Jiri Olsa @ 2015-03-31 16:22 ` Don Zickus 2015-04-02 12:23 ` [tip:perf/core] perf tools: " tip-bot for David Ahern 3 siblings, 0 replies; 11+ messages in thread From: Don Zickus @ 2015-03-31 16:22 UTC (permalink / raw) To: David Ahern; +Cc: acme, linux-kernel, Joe Mario, Jiri Olsa On Mon, Mar 30, 2015 at 02:35:57PM -0600, David Ahern wrote: > Rather than parsing /proc/pid/status file one line at a time, read > it into a buffer in one shot and search for all strings in one pass. > > tgid conversion also simplified -- removing the isspace walk. As > noted by Arnaldo those are not needed for atoi == strtol calls. Seeing Jiri is happy now. :-) Acked-by: Don Zickus <dzickus@redhat.com> > > Signed-off-by: David Ahern <dsahern@gmail.com> > Cc: Don Zickus <dzickus@redhat.com> > Cc: Joe Mario <jmario@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> > --- > v2: > - removed the isspace checks on tgid string > > tools/perf/util/event.c | 72 ++++++++++++++++++++++++++++++------------------- > 1 file changed, 44 insertions(+), 28 deletions(-) > > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > index d5efa5092ce6..023dd3548a94 100644 > --- a/tools/perf/util/event.c > +++ b/tools/perf/util/event.c > @@ -49,48 +49,64 @@ static struct perf_sample synth_sample = { > .period = 1, > }; > > +/* > + * Assumes that the first 4095 bytes of /proc/pid/stat contains > + * the comm and tgid. > + */ > static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > { > char filename[PATH_MAX]; > - char bf[BUFSIZ]; > - FILE *fp; > - size_t size = 0; > + char bf[4096]; > + int fd; > + size_t size = 0, n; > pid_t tgid = -1; > + char *nl, *name, *tgids; > > snprintf(filename, sizeof(filename), "/proc/%d/status", pid); > > - fp = fopen(filename, "r"); > - if (fp == NULL) { > + fd = open(filename, O_RDONLY); > + if (fd < 0) { > pr_debug("couldn't open %s\n", filename); > return 0; > } > > - while (!comm[0] || (tgid < 0)) { > - if (fgets(bf, sizeof(bf), fp) == NULL) { > - pr_warning("couldn't get COMM and pgid, malformed %s\n", > - filename); > - break; > - } > + n = read(fd, bf, sizeof(bf) - 1); > + close(fd); > + if (n <= 0) { > + pr_warning("Couldn't get COMM and tgid for pid %d\n", > + pid); > + return -1; > + } > + bf[n] = '\0'; > > - if (memcmp(bf, "Name:", 5) == 0) { > - char *name = bf + 5; > - while (*name && isspace(*name)) > - ++name; > - size = strlen(name) - 1; > - if (size >= len) > - size = len - 1; > - memcpy(comm, name, size); > - comm[size] = '\0'; > - > - } else if (memcmp(bf, "Tgid:", 5) == 0) { > - char *tgids = bf + 5; > - while (*tgids && isspace(*tgids)) > - ++tgids; > - tgid = atoi(tgids); > - } > + name = strstr(bf, "Name:"); > + tgids = strstr(bf, "Tgid:"); > + > + if (name) { > + name += 5; /* strlen("Name:") */ > + > + while (*name && isspace(*name)) > + ++name; > + > + nl = strchr(name, '\n'); > + if (nl) > + *nl = '\0'; > + > + size = strlen(name); > + if (size >= len) > + size = len - 1; > + memcpy(comm, name, size); > + comm[size] = '\0'; > + } else { > + pr_debug("Name: string not found for pid %d\n", pid); > } > > - fclose(fp); > + if (tgids) { > + tgids += 5; /* strlen("Tgid:") */ > + tgid = atoi(tgids); > + } else { > + pr_debug("Tgid: string not found for pid %d\n", pid); > + } > > return tgid; > } > -- > 2.2.1 > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [tip:perf/core] perf tools: Refactor comm/tgid lookup 2015-03-30 20:35 [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup David Ahern ` (2 preceding siblings ...) 2015-03-31 16:22 ` Don Zickus @ 2015-04-02 12:23 ` tip-bot for David Ahern 3 siblings, 0 replies; 11+ messages in thread From: tip-bot for David Ahern @ 2015-04-02 12:23 UTC (permalink / raw) To: linux-tip-commits Cc: mingo, tglx, acme, dsahern, jmario, hpa, linux-kernel, jolsa, dzickus Commit-ID: 5aa0b030e8d29d6719c144818814b519cfcb105c Gitweb: http://git.kernel.org/tip/5aa0b030e8d29d6719c144818814b519cfcb105c Author: David Ahern <dsahern@gmail.com> AuthorDate: Mon, 30 Mar 2015 14:35:57 -0600 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Tue, 31 Mar 2015 17:52:30 -0300 perf tools: Refactor comm/tgid lookup Rather than parsing /proc/pid/status file one line at a time, read it into a buffer in one shot and search for all strings in one pass. tgid conversion also simplified -- removing the isspace walk. As noted by Arnaldo those are not needed for atoi == strtol calls. Signed-off-by: David Ahern <dsahern@gmail.com> Acked-by: Don Zickus <dzickus@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Joe Mario <jmario@redhat.com> Link: http://lkml.kernel.org/r/1427747758-18510-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/event.c | 72 ++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index d5efa50..023dd35 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -49,48 +49,64 @@ static struct perf_sample synth_sample = { .period = 1, }; +/* + * Assumes that the first 4095 bytes of /proc/pid/stat contains + * the comm and tgid. + */ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) { char filename[PATH_MAX]; - char bf[BUFSIZ]; - FILE *fp; - size_t size = 0; + char bf[4096]; + int fd; + size_t size = 0, n; pid_t tgid = -1; + char *nl, *name, *tgids; snprintf(filename, sizeof(filename), "/proc/%d/status", pid); - fp = fopen(filename, "r"); - if (fp == NULL) { + fd = open(filename, O_RDONLY); + if (fd < 0) { pr_debug("couldn't open %s\n", filename); return 0; } - while (!comm[0] || (tgid < 0)) { - if (fgets(bf, sizeof(bf), fp) == NULL) { - pr_warning("couldn't get COMM and pgid, malformed %s\n", - filename); - break; - } + n = read(fd, bf, sizeof(bf) - 1); + close(fd); + if (n <= 0) { + pr_warning("Couldn't get COMM and tgid for pid %d\n", + pid); + return -1; + } + bf[n] = '\0'; - if (memcmp(bf, "Name:", 5) == 0) { - char *name = bf + 5; - while (*name && isspace(*name)) - ++name; - size = strlen(name) - 1; - if (size >= len) - size = len - 1; - memcpy(comm, name, size); - comm[size] = '\0'; - - } else if (memcmp(bf, "Tgid:", 5) == 0) { - char *tgids = bf + 5; - while (*tgids && isspace(*tgids)) - ++tgids; - tgid = atoi(tgids); - } + name = strstr(bf, "Name:"); + tgids = strstr(bf, "Tgid:"); + + if (name) { + name += 5; /* strlen("Name:") */ + + while (*name && isspace(*name)) + ++name; + + nl = strchr(name, '\n'); + if (nl) + *nl = '\0'; + + size = strlen(name); + if (size >= len) + size = len - 1; + memcpy(comm, name, size); + comm[size] = '\0'; + } else { + pr_debug("Name: string not found for pid %d\n", pid); } - fclose(fp); + if (tgids) { + tgids += 5; /* strlen("Tgid:") */ + tgid = atoi(tgids); + } else { + pr_debug("Tgid: string not found for pid %d\n", pid); + } return tgid; } ^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-04-02 12:24 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-03-30 20:35 [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup David Ahern 2015-03-30 20:35 ` [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events David Ahern 2015-03-31 14:10 ` Jiri Olsa 2015-03-31 14:17 ` Jiri Olsa 2015-03-31 14:35 ` Jiri Olsa 2015-03-31 16:23 ` Don Zickus 2015-04-02 12:23 ` [tip:perf/core] perf tools: " tip-bot for David Ahern 2015-03-31 14:35 ` [PATCH v2 1/2] perf tool: Refactor comm/tgid lookup Jiri Olsa 2015-03-31 15:55 ` Arnaldo Carvalho de Melo 2015-03-31 16:22 ` Don Zickus 2015-04-02 12:23 ` [tip:perf/core] perf tools: " tip-bot for David Ahern
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.