aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-daemon.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-03-28 13:22:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-03-28 13:22:54 -0700
commitf9e2bb42cf0db3a624d295122db3475aa3e7ad18 (patch)
tree288634eac965d992ae8cabe8dfb8ae7e66c3830f /tools/perf/builtin-daemon.c
parentMerge tag 'auxdisplay-for-linus-v5.12-rc6' of git://github.com/ojeda/linux (diff)
parentperf test: Change to use bash for daemon test (diff)
downloadlinux-dev-f9e2bb42cf0db3a624d295122db3475aa3e7ad18.tar.xz
linux-dev-f9e2bb42cf0db3a624d295122db3475aa3e7ad18.zip
Merge tag 'perf-tools-fixes-for-v5.12-2020-03-28' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
Pull perf tooling fixes from Arnaldo Carvalho de Melo: - Avoid write of uninitialized memory when generating PERF_RECORD_MMAP* records. - Fix 'perf top' BPF support related crash with perf_event_paranoid=3 + kptr_restrict. - Validate raw event with sysfs exported format bits. - Fix waipid on SIGCHLD delivery bugs in 'perf daemon'. - Change to use bash for daemon test on Debian, where the default is dash and thus fails for use of bashisms in this test. - Fix memory leak in vDSO found using ASAN. - Remove now useless (due to the fact that BPF now supports static vars) failing sub test "BPF relocation checker". - Fix auxtrace queue conflict. - Sync linux/kvm.h with the kernel sources. * tag 'perf-tools-fixes-for-v5.12-2020-03-28' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: perf test: Change to use bash for daemon test perf record: Fix memory leak in vDSO found using ASAN perf test: Remove now useless failing sub test "BPF relocation checker" perf daemon: Return from kill functions perf daemon: Force waipid for all session on SIGCHLD delivery perf top: Fix BPF support related crash with perf_event_paranoid=3 + kptr_restrict perf pmu: Validate raw event with sysfs exported format bits perf synthetic events: Avoid write of uninitialized memory when generating PERF_RECORD_MMAP* records tools headers UAPI: Sync linux/kvm.h with the kernel sources perf synthetic-events: Fix uninitialized 'kernel_thread' variable perf auxtrace: Fix auxtrace queue conflict
Diffstat (limited to 'tools/perf/builtin-daemon.c')
-rw-r--r--tools/perf/builtin-daemon.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c
index ace8772a4f03..7c4a9d424a64 100644
--- a/tools/perf/builtin-daemon.c
+++ b/tools/perf/builtin-daemon.c
@@ -402,35 +402,42 @@ static pid_t handle_signalfd(struct daemon *daemon)
int status;
pid_t pid;
+ /*
+ * Take signal fd data as pure signal notification and check all
+ * the sessions state. The reason is that multiple signals can get
+ * coalesced in kernel and we can receive only single signal even
+ * if multiple SIGCHLD were generated.
+ */
err = read(daemon->signal_fd, &si, sizeof(struct signalfd_siginfo));
- if (err != sizeof(struct signalfd_siginfo))
+ if (err != sizeof(struct signalfd_siginfo)) {
+ pr_err("failed to read signal fd\n");
return -1;
+ }
list_for_each_entry(session, &daemon->sessions, list) {
+ if (session->pid == -1)
+ continue;
- if (session->pid != (int) si.ssi_pid)
+ pid = waitpid(session->pid, &status, WNOHANG);
+ if (pid <= 0)
continue;
- pid = waitpid(session->pid, &status, 0);
- if (pid == session->pid) {
- if (WIFEXITED(status)) {
- pr_info("session '%s' exited, status=%d\n",
- session->name, WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- pr_info("session '%s' killed (signal %d)\n",
- session->name, WTERMSIG(status));
- } else if (WIFSTOPPED(status)) {
- pr_info("session '%s' stopped (signal %d)\n",
- session->name, WSTOPSIG(status));
- } else {
- pr_info("session '%s' Unexpected status (0x%x)\n",
- session->name, status);
- }
+ if (WIFEXITED(status)) {
+ pr_info("session '%s' exited, status=%d\n",
+ session->name, WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ pr_info("session '%s' killed (signal %d)\n",
+ session->name, WTERMSIG(status));
+ } else if (WIFSTOPPED(status)) {
+ pr_info("session '%s' stopped (signal %d)\n",
+ session->name, WSTOPSIG(status));
+ } else {
+ pr_info("session '%s' Unexpected status (0x%x)\n",
+ session->name, status);
}
session->state = KILL;
session->pid = -1;
- return pid;
}
return 0;
@@ -443,7 +450,6 @@ static int daemon_session__wait(struct daemon_session *session, struct daemon *d
.fd = daemon->signal_fd,
.events = POLLIN,
};
- pid_t wpid = 0, pid = session->pid;
time_t start;
start = time(NULL);
@@ -452,7 +458,7 @@ static int daemon_session__wait(struct daemon_session *session, struct daemon *d
int err = poll(&pollfd, 1, 1000);
if (err > 0) {
- wpid = handle_signalfd(daemon);
+ handle_signalfd(daemon);
} else if (err < 0) {
perror("failed: poll\n");
return -1;
@@ -460,7 +466,7 @@ static int daemon_session__wait(struct daemon_session *session, struct daemon *d
if (start + secs < time(NULL))
return -1;
- } while (wpid != pid);
+ } while (session->pid != -1);
return 0;
}
@@ -902,7 +908,9 @@ static void daemon_session__kill(struct daemon_session *session,
daemon_session__signal(session, SIGKILL);
break;
default:
- break;
+ pr_err("failed to wait for session %s\n",
+ session->name);
+ return;
}
how++;
@@ -955,7 +963,8 @@ static void daemon__kill(struct daemon *daemon)
daemon__signal(daemon, SIGKILL);
break;
default:
- break;
+ pr_err("failed to wait for sessions\n");
+ return;
}
how++;
@@ -1344,7 +1353,7 @@ out:
close(sock_fd);
if (conf_fd != -1)
close(conf_fd);
- if (conf_fd != -1)
+ if (signal_fd != -1)
close(signal_fd);
pr_info("daemon exited\n");