From: Swapnil Sapkal Date: Wed, 20 May 2026 10:20:16 +0000 (+0000) Subject: perf sched stats: Fix SIGCHLD vs pause() race in schedstat_live() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b8c90e06622308ff4b6c14260baee6fad064289;p=thirdparty%2Flinux.git perf sched stats: Fix SIGCHLD vs pause() race in schedstat_live() perf_sched__schedstat_live() has the same lost-wakeup race as perf_sched__schedstat_record(): a short-lived workload's SIGCHLD can be consumed by the signal handler before pause() is entered, hanging the process. Apply the same fix: replace pause() with a loop checking the 'done' flag and using waitpid(WNOHANG) for the workload case. Suggested-by: Namhyung Kim Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Swapnil Sapkal Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Ravi Bangoria Signed-off-by: Arnaldo Carvalho de Melo --- diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 4f54a08e66728..812a1b0d56d6e 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -4743,6 +4743,7 @@ static int perf_sched__schedstat_live(struct perf_sched *sched, int reset = 0; int err = 0; + done = 0; signal(SIGINT, sighandler); signal(SIGCHLD, sighandler); signal(SIGTERM, sighandler); @@ -4788,8 +4789,11 @@ static int perf_sched__schedstat_live(struct perf_sched *sched, if (argc) evlist__start_workload(evlist); - /* wait for signal */ - pause(); + while (!done) { + if (argc && waitpid(evlist->workload.pid, NULL, WNOHANG) > 0) + break; + sleep(1); + } if (reset) { err = disable_sched_schedstat();