All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: "Eric W. Biederman" <ebiederm@xmission.com>,
	linux-kernel@vger.kernel.org
Cc: "Ingo Molnar" <mingo@redhat.com>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>,
	"Kalle Valo" <kvalo@kernel.org>,
	"Johannes Berg" <johannes@sipsolutions.net>
Subject: Re: [PATCH v3] signal: break out of wait loops on kthread_stop()
Date: Mon, 4 Jul 2022 14:22:26 +0200	[thread overview]
Message-ID: <YsLbggVXONPJcZsn@zx2c4.com> (raw)
In-Reply-To: <20220628161441.892925-1-Jason@zx2c4.com>

Hey Eric,

On Tue, Jun 28, 2022 at 06:14:41PM +0200, Jason A. Donenfeld wrote:
> I was recently surprised to learn that msleep_interruptible(),
> wait_for_completion_interruptible_timeout(), and related functions
> simply hung when I called kthread_stop() on kthreads using them. The
> solution to fixing the case with msleep_interruptible() was more simply
> to move to schedule_timeout_interruptible(). Why?
> 
> The reason is that msleep_interruptible(), and many functions just like
> it, has a loop like this:
> 
>         while (timeout && !signal_pending(current))
>                 timeout = schedule_timeout_interruptible(timeout);
> 
> The call to kthread_stop() woke up the thread, so schedule_timeout_
> interruptible() returned early, but because signal_pending() returned
> true, it went back into another timeout, which was never woken up.
> 
> This wait loop pattern is common to various pieces of code, and I
> suspect that the subtle misuse in a kthread that caused a deadlock in
> the code I looked at last week is also found elsewhere.
> 
> So this commit causes signal_pending() to return true when
> kthread_stop() is called, by setting TIF_NOTIFY_SIGNAL.
> 
> The same also applies to the similar kthread_park() functionality.
> 
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Eric W. Biederman <ebiederm@xmission.com>
> Cc: Toke Høiland-Jørgensen <toke@redhat.com>
> Cc: Kalle Valo <kvalo@kernel.org>
> Cc: Johannes Berg <johannes@sipsolutions.net>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  kernel/kthread.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/kernel/kthread.c b/kernel/kthread.c
> index 3c677918d8f2..63d5a1f4cb93 100644
> --- a/kernel/kthread.c
> +++ b/kernel/kthread.c
> @@ -661,12 +661,14 @@ int kthread_park(struct task_struct *k)
>  
>  	set_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
>  	if (k != current) {
> +		test_and_set_tsk_thread_flag(k, TIF_NOTIFY_SIGNAL);
>  		wake_up_process(k);
>  		/*
>  		 * Wait for __kthread_parkme() to complete(), this means we
>  		 * _will_ have TASK_PARKED and are about to call schedule().
>  		 */
>  		wait_for_completion(&kthread->parked);
> +		clear_tsk_thread_flag(k, TIF_NOTIFY_SIGNAL);
>  		/*
>  		 * Now wait for that schedule() to complete and the task to
>  		 * get scheduled out.
> @@ -704,8 +706,10 @@ int kthread_stop(struct task_struct *k)
>  	kthread = to_kthread(k);
>  	set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
>  	kthread_unpark(k);
> +	test_and_set_tsk_thread_flag(k, TIF_NOTIFY_SIGNAL);
>  	wake_up_process(k);
>  	wait_for_completion(&kthread->exited);
> +	clear_tsk_thread_flag(k, TIF_NOTIFY_SIGNAL);
>  	ret = kthread->result;
>  	put_task_struct(k);
>  
> -- 
> 2.35.1
> 

Is this more to the tune of what you had in mind in your message [1]?

Jason

[1] https://lore.kernel.org/lkml/877d51udc7.fsf@email.froward.int.ebiederm.org/

  reply	other threads:[~2022-07-04 12:22 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-27 12:00 [PATCH] signal: break out of wait loops on kthread_stop() Jason A. Donenfeld
2022-06-27 13:27 ` Peter Zijlstra
2022-06-27 14:54   ` Jason A. Donenfeld
2022-06-27 14:57     ` [PATCH v2] " Jason A. Donenfeld
2022-06-27 19:16       ` Eric W. Biederman
2022-06-28 15:59         ` Jason A. Donenfeld
2022-06-28 16:14           ` [PATCH v3] " Jason A. Donenfeld
2022-07-04 12:22             ` Jason A. Donenfeld [this message]
2022-07-11 17:53               ` Jason A. Donenfeld
2022-07-11 18:57                 ` Eric W. Biederman
2022-07-11 20:18                   ` Jason A. Donenfeld
2022-07-11 20:21                     ` [PATCH v4] " Jason A. Donenfeld
2022-07-11 22:05                       ` Eric W. Biederman
2022-07-11 23:21                         ` [PATCH v5] " Jason A. Donenfeld
2022-07-12  0:00                           ` Eric W. Biederman
2022-07-12  0:18                             ` Jason A. Donenfeld
2022-07-11 22:04                     ` [PATCH v3] " Eric W. Biederman

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=YsLbggVXONPJcZsn@zx2c4.com \
    --to=jason@zx2c4.com \
    --cc=ebiederm@xmission.com \
    --cc=johannes@sipsolutions.net \
    --cc=kvalo@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=toke@redhat.com \
    /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.