Skip to content

Commit

Permalink
perf evlist: Enhance perf_evlist__start_workload()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Steven Rostedt <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
Namhyung Kim authored and acmel committed Jul 8, 2013
1 parent 4a4d371 commit bcf3145
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion tools/perf/util/evlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -837,10 +838,17 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
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;
Expand Down

0 comments on commit bcf3145

Please sign in to comment.