summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2013-06-26 16:14:15 +0900
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-07-08 17:38:30 -0300
commitbcf3145fbeb1bd91ad2ca67b1946077530f7bfb1 (patch)
treeda2034b1ccc9f8fce8e830085bc35a1d9655cccb
parent4a4d371a4dfbd3b84a7eab8d535d4c7c3647b09e (diff)
perf evlist: Enhance perf_evlist__start_workload()
When perf tries to start a workload, it relies on a pipe which the workload was blocked for reading. After closing the pipe on the parent, the workload (child) can start the actual work via exec(). However, if another process was forked after creating a workload, this mechanism cannot work since the other process (child) also inherits the pipe, so that closing the pipe in parent cannot unblock the workload. Fix it by using explicit write call can then closing it. For similar reason, the pipe fd on parent should be marked as CLOEXEC so that it can be closed after another child exec'ed. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/1372230862-15861-13-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/evlist.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 99b43dd18c57..8065ce8fa9a5 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -821,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
goto out_close_pipes;
}
+ fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
evlist->workload.cork_fd = go_pipe[1];
close(child_ready_pipe[0]);
return 0;
@@ -837,10 +838,17 @@ out_close_ready_pipe:
int perf_evlist__start_workload(struct perf_evlist *evlist)
{
if (evlist->workload.cork_fd > 0) {
+ char bf;
+ int ret;
/*
* Remove the cork, let it rip!
*/
- return close(evlist->workload.cork_fd);
+ ret = write(evlist->workload.cork_fd, &bf, 1);
+ if (ret < 0)
+ perror("enable to write to pipe");
+
+ close(evlist->workload.cork_fd);
+ return ret;
}
return 0;