mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
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 <namhyung@kernel.org> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Swapnil Sapkal <swapnil.sapkal@amd.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
5b8c90e066
commit
35c9fb2200
|
|
@ -31,6 +31,7 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <semaphore.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
|
@ -1915,8 +1916,11 @@ static int __cmd_report(bool display_info)
|
|||
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user