From: Swapnil Sapkal Date: Wed, 20 May 2026 10:20:17 +0000 (+0000) Subject: perf lock contention: Fix SIGCHLD vs pause() race in __cmd_contention() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35c9fb22000f1ce10c0f3627d30fa8763e721719;p=thirdparty%2Fkernel%2Fstable.git perf lock contention: Fix SIGCHLD vs pause() race in __cmd_contention() __cmd_contention() suffers from the same lost-wakeup race as the perf sched stats paths: 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-lock.c b/tools/perf/builtin-lock.c index 064b3aa4bad7..94a8c35abb0b 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1915,8 +1916,11 @@ out_delete: return err; } +static volatile sig_atomic_t done; + static void sighandler(int sig __maybe_unused) { + done = 1; } static int check_lock_contention_options(const struct option *options, @@ -2054,6 +2058,7 @@ static int __cmd_contention(int argc, const char **argv) goto out_delete; } + done = 0; signal(SIGINT, sighandler); signal(SIGCHLD, sighandler); signal(SIGTERM, sighandler); @@ -2121,8 +2126,11 @@ static int __cmd_contention(int argc, const char **argv) if (argc) evlist__start_workload(con.evlist); - /* wait for signal */ - pause(); + while (!done) { + if (argc && waitpid(con.evlist->workload.pid, NULL, WNOHANG) > 0) + break; + sleep(1); + } lock_contention_stop(); lock_contention_read(&con);