Commit bcf3145f authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

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: default avatarNamhyung 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.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 4a4d371a
...@@ -821,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, ...@@ -821,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
goto out_close_pipes; goto out_close_pipes;
} }
fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
evlist->workload.cork_fd = go_pipe[1]; evlist->workload.cork_fd = go_pipe[1];
close(child_ready_pipe[0]); close(child_ready_pipe[0]);
return 0; return 0;
...@@ -837,10 +838,17 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, ...@@ -837,10 +838,17 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
int perf_evlist__start_workload(struct perf_evlist *evlist) int perf_evlist__start_workload(struct perf_evlist *evlist)
{ {
if (evlist->workload.cork_fd > 0) { if (evlist->workload.cork_fd > 0) {
char bf;
int ret;
/* /*
* Remove the cork, let it rip! * 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; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment