* [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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox