Skip to content

Commit bcf3145

Browse files
Namhyung Kimacmel
authored andcommitted
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 <[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]>
1 parent 4a4d371 commit bcf3145

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

tools/perf/util/evlist.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
821821
goto out_close_pipes;
822822
}
823823

824+
fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
824825
evlist->workload.cork_fd = go_pipe[1];
825826
close(child_ready_pipe[0]);
826827
return 0;
@@ -837,10 +838,17 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
837838
int perf_evlist__start_workload(struct perf_evlist *evlist)
838839
{
839840
if (evlist->workload.cork_fd > 0) {
841+
char bf;
842+
int ret;
840843
/*
841844
* Remove the cork, let it rip!
842845
*/
843-
return close(evlist->workload.cork_fd);
846+
ret = write(evlist->workload.cork_fd, &bf, 1);
847+
if (ret < 0)
848+
perror("enable to write to pipe");
849+
850+
close(evlist->workload.cork_fd);
851+
return ret;
844852
}
845853

846854
return 0;

0 commit comments

Comments
 (0)