All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Charles <daniel.charles@intel.com>
To: Gustavo Sousa <gustavo.sousa@intel.com>, <igt-dev@lists.freedesktop.org>
Subject: Re: [i-g-t,1/2] lib/igt_core: Check if helper proc was alive before kill()
Date: Tue, 13 Oct 2026 11:39:39 -0700	[thread overview]
Message-ID: <1f2844aa-cb5c-4c77-bfbf-a8e473698ea5@intel.com> (raw)
In-Reply-To: <87o6cxa3ig.fsf@intel.com>


On 10/13/2026 10:56 AM, Gustavo Sousa wrote:
> Daniel Charles <daniel.charles@intel.com> writes:
>
>> On 10/7/2026 7:16 AM, Gustavo Sousa wrote:
>>> The function igt_stop_helper() does a sanity check by verifying if the
>>> helper process died "too early", however it does that by checking if
>>> it was terminated due to not handling the signal used in the kill()
>>> call.
>>>
>>> That logic has a flaw though: it the helper process gracefully handles
>>> the signal sent by kill() and exits normally, igt_stop_helper() will
>>> mistakenly take that as dying too early, because WIFSIGNALED(status)
>>> will be false.
>>>
>>> That's the case with the pw-reserve process: in an upcoming change we
>>> will change pipewire_reserve_wait() to call it with execlp().  Because
>>> it handles SIGTERM and exits normally, a warning and assertion failure
>>> would happen with the current logic.
>>>
>>> Fix that by checking if the process was alive before calling kill().
>>>
>>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>>> ---
>>>    lib/igt_core.c | 20 +++++++++-----------
>>>    1 file changed, 9 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/lib/igt_core.c b/lib/igt_core.c
>>> index 8ee9432923e6..d9949ea131f8 100644
>>> --- a/lib/igt_core.c
>>> +++ b/lib/igt_core.c
>>> @@ -2652,13 +2652,6 @@ int igt_wait_helper(struct igt_helper_process *proc)
>>>    	return status;
>>>    }
>>>    
>>> -static bool helper_was_alive(struct igt_helper_process *proc,
>>> -			     int status)
>>> -{
>>> -	return (WIFSIGNALED(status) &&
>>> -		WTERMSIG(status) == (proc->use_SIGKILL ? SIGKILL : SIGTERM));
>>> -}
>>> -
>>>    /**
>>>     * igt_stop_helper:
>>>     * @proc: #igt_helper_process structure
>>> @@ -2670,17 +2663,22 @@ static bool helper_was_alive(struct igt_helper_process *proc,
>>>    void igt_stop_helper(struct igt_helper_process *proc)
>>>    {
>>>    	int status;
>>> +	int ret;
>>>    
>>>    	if (!proc->running) /* never even started */
>>>    		return;
>>>    
>>> +	ret = waitpid(proc->pid, &status, WNOHANG);
>> put waitpid in a do/while loop to catch any EINT return that may need a
>> retry.
> Do you mean EINTR? EINTR would happen only if WNOHANG was not passed in
> options.
Yes it was a typo  and you're right on WNOHANG according to [1]
>
> This call is to check if the child process was still alive by the time
> we are about to kill it.
>
>>> +
>>> +	if (ret == proc->pid)
>>> +		igt_debug("Helper died too early with status=%d\n", status);
>>> +
>>>    	/* failure here means the pid is already dead and so waiting is safe */
>>>    	kill(proc->pid, proc->use_SIGKILL ? SIGKILL : SIGTERM);
>>>    
>>> -	status = igt_wait_helper(proc);
>>> -	if (!helper_was_alive(proc, status))
>>> -		igt_debug("Helper died too early with status=%d\n", status);
>>> -	assert(helper_was_alive(proc, status));
>>> +	assert(ret == 0);
>> This assert can be moved before kill call to make sure the correct
>> process is killed.
> Hm... This function already assumes proc->pid is the correct process to
> be killed.  The objective of the waitpid() call above is rather to check
> if the process was still alive (the expected scenario).
>
> If we move this assert() to happen before the kill() call, we risk
> leaking the process, because an assertion failure would keep us from
> killing the child process.

The process will be already reaped after waitpid if it returns the PID, 
then kill may signal a different process that took the same PID.

So call kill only when ret == 0 ? and keep the assert in the current place.


[1] https://man7.org/linux/man-pages/man2/wait.2.html#ERRORS

-- 

Daniel.

> --
> Gustavo Sousa
>
>> -- Daniel.
>>
>>> +
>>> +	igt_wait_helper(proc);
>>>    }
>>>    
>>>    static void children_exit_handler(int sig)

  reply	other threads:[~2026-10-13 18:40 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-07 14:16 [PATCH i-g-t 0/2] Fix igt_runner hang and resource leak associated with pw-reserve Gustavo Sousa
2026-10-07 14:16 ` [PATCH i-g-t 1/2] lib/igt_core: Check if helper proc was alive before kill() Gustavo Sousa
2026-10-09 22:55   ` [i-g-t,1/2] " Daniel Charles
2026-10-13 17:56     ` Gustavo Sousa
2026-10-13 18:39       ` Daniel Charles [this message]
2026-10-13 18:53         ` Gustavo Sousa
2026-10-07 14:16 ` [PATCH i-g-t 2/2] lib/igt_aux: Call pw-reserve with execlp() Gustavo Sousa
2026-10-07 14:34 ` [PATCH i-g-t 0/2] Fix igt_runner hang and resource leak associated with pw-reserve Gustavo Sousa
2026-10-07 16:31 ` ✓ i915.CI.BAT: success for " Patchwork
2026-10-07 16:40 ` ✓ Xe.CI.BAT: " Patchwork
2026-10-07 19:36 ` ✓ Xe.CI.FULL: " Patchwork
2026-10-07 22:27 ` ✗ i915.CI.Full: failure " Patchwork

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=1f2844aa-cb5c-4c77-bfbf-a8e473698ea5@intel.com \
    --to=daniel.charles@intel.com \
    --cc=gustavo.sousa@intel.com \
    --cc=igt-dev@lists.freedesktop.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.