All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Jiri Olsa <jolsa@kernel.org>
Cc: Ian Rogers <irogers@google.com>,
	lkml <linux-kernel@vger.kernel.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Ingo Molnar <mingo@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Namhyung Kim <namhyung@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Michael Petlan <mpetlan@redhat.com>
Subject: Re: [PATCH 1/2] perf daemon: Force waipid for all session on SIGCHLD delivery
Date: Wed, 24 Mar 2021 10:24:46 -0300	[thread overview]
Message-ID: <YFs9nkXP46Olg5mZ@kernel.org> (raw)
In-Reply-To: <20210320221013.1619613-1-jolsa@kernel.org>

Em Sat, Mar 20, 2021 at 11:10:12PM +0100, Jiri Olsa escreveu:
> If we don't process SIGCHLD before another comes, we will
> see just one SIGCHLD as a result. In this case current code
> will miss exit notification for a session and wait forever.
> 
> Adding extra waitpid check for all sessions when SIGCHLD
> is received, to make sure we don't miss any session exit.
> 
> Also fix close condition for signal_fd.

Thanks, applied.

- Arnaldo

 
> Reported-by: Ian Rogers <irogers@google.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/builtin-daemon.c | 50 +++++++++++++++++++++----------------
>  1 file changed, 28 insertions(+), 22 deletions(-)
> 
> diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c
> index ace8772a4f03..4697493842f5 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;
>  }
> @@ -1344,7 +1350,7 @@ static int __cmd_start(struct daemon *daemon, struct option parent_options[],
>  		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");
> -- 
> 2.30.2
> 

-- 

- Arnaldo

      parent reply	other threads:[~2021-03-24 13:25 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-20 22:10 [PATCH 1/2] perf daemon: Force waipid for all session on SIGCHLD delivery Jiri Olsa
2021-03-20 22:10 ` [PATCH 2/2] perf daemon: Return from kill functions Jiri Olsa
2021-03-24 13:24 ` Arnaldo Carvalho de Melo [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YFs9nkXP46Olg5mZ@kernel.org \
    --to=acme@kernel.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@kernel.org \
    --cc=mpetlan@redhat.com \
    --cc=namhyung@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.