4.20-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit 8a99255a50c0b4c2a449b96fd8d45fcc8d72c701 ]
We hit a 'perf stat' issue by using following script:
#!/bin/bash
sleep 1000 & exec perf stat -a -e cycles -I1000 -- sleep 5
Since "perf stat" is launched by exec, the "sleep 1000" would be the child process of "perf stat". The wait4() call will not return because it's waiting for the child process "sleep 1000" to end. So 'perf stat' doesn't return even after 5s passes.
This patch lets 'perf stat' return when the specified child process ends (in this case, the specified child process is "sleep 5").
Committer testing:
# cat test.sh #!/bin/bash
sleep 10 & exec perf stat -a -e cycles -I1000 -- sleep 5 #
Before:
# time ./test.sh # time counts unit events 1.001113090 108,453,351 cycles 2.002062196 142,075,435 cycles 3.002896194 164,801,068 cycles 4.003731666 107,062,140 cycles 5.002068867 112,241,832 cycles
real 0m10.066s user 0m0.016s sys 0m0.101s #
After:
# time ./test.sh # time counts unit events 1.001016096 91,412,027 cycles 2.002014963 124,063,708 cycles 3.002883964 125,993,929 cycles 4.003706470 120,465,734 cycles 5.002006778 163,560,355 cycles
real 0m5.123s user 0m0.014s sys 0m0.105s #
Signed-off-by: Jin Yao yao.jin@linux.intel.com Reviewed-by: Jiri Olsa jolsa@kernel.org Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Kan Liang kan.liang@linux.intel.com Cc: Peter Zijlstra peterz@infradead.org Link: http://lkml.kernel.org/r/1546501245-4512-1-git-send-email-yao.jin@linux.inte... Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-stat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 1410d66192f7..63a3afc7f32b 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -561,7 +561,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) break; } } - wait4(child_pid, &status, 0, &stat_config.ru_data); + if (child_pid != -1) + wait4(child_pid, &status, 0, &stat_config.ru_data);
if (workload_exec_errno) { const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));