From: Lai Jiangshan <laijs@cn.fujitsu.com>
To: Tejun Heo <tj@kernel.org>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH wq/for-3.14-fixes] workqueue: ensure @task is valid across kthread_stop()
Date: Wed, 19 Feb 2014 11:39:42 +0800 [thread overview]
Message-ID: <5304277E.4040705@cn.fujitsu.com> (raw)
In-Reply-To: <20140218213713.GC31892@mtj.dyndns.org>
On 02/19/2014 05:37 AM, Tejun Heo wrote:
> Hello, Lai.
>
> I massaged the patch a bit and applied it to wq/for-3.14-fixes.
>
> Thanks.
> -------- 8< --------
>>From 5bdfff96c69a4d5ab9c49e60abf9e070ecd2acbb Mon Sep 17 00:00:00 2001
> From: Lai Jiangshan <laijs@cn.fujitsu.com>
> Date: Sat, 15 Feb 2014 22:02:28 +0800
>
> When a kworker should die, the kworkre is notified through WORKER_DIE
> flag instead of kthread_should_stop(). This, IIRC, is primarily to
> keep the test synchronized inside worker_pool lock. WORKER_DIE is
> first set while holding pool->lock, the lock is dropped and
> kthread_stop() is called.
>
> Unfortunately, this means that there's a slight chance that the target
> kworker may see WORKER_DIE before kthread_stop() finishes and exits
> and frees the target task before or during kthread_stop().
>
> Fix it by pinning the target task before setting WORKER_DIE and
> putting it after kthread_stop() is done.
>
> tj: Improved patch description and comment. Moved pinning above
> WORKER_DIE for better signify what it's protecting.
>
> CC: stable@vger.kernel.org
I think no one hit this bug. So I add this stable TAG?
(Jason's bug-report drives me to review the workqueue harder,
and I found this possible bug, but I think it is irrespective
with Jason's bug-report.)
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> ---
> kernel/workqueue.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index 82ef9f3..193e977 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -1851,6 +1851,12 @@ static void destroy_worker(struct worker *worker)
> if (worker->flags & WORKER_IDLE)
> pool->nr_idle--;
>
> + /*
> + * Once WORKER_DIE is set, the kworker may destroy itself at any
> + * point. Pin to ensure the task stays until we're done with it.
> + */
> + get_task_struct(worker->task);
> +
> list_del_init(&worker->entry);
> worker->flags |= WORKER_DIE;
>
> @@ -1859,6 +1865,7 @@ static void destroy_worker(struct worker *worker)
> spin_unlock_irq(&pool->lock);
>
> kthread_stop(worker->task);
> + put_task_struct(worker->task);
> kfree(worker);
>
> spin_lock_irq(&pool->lock);
WARNING: multiple messages have this Message-ID (diff)
From: Lai Jiangshan <laijs@cn.fujitsu.com>
To: Tejun Heo <tj@kernel.org>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH wq/for-3.14-fixes] workqueue: ensure @task is valid across kthread_stop()
Date: Wed, 19 Feb 2014 11:39:42 +0800 [thread overview]
Message-ID: <5304277E.4040705@cn.fujitsu.com> (raw)
In-Reply-To: <20140218213713.GC31892@mtj.dyndns.org>
On 02/19/2014 05:37 AM, Tejun Heo wrote:
> Hello, Lai.
>
> I massaged the patch a bit and applied it to wq/for-3.14-fixes.
>
> Thanks.
> -------- 8< --------
>>>From 5bdfff96c69a4d5ab9c49e60abf9e070ecd2acbb Mon Sep 17 00:00:00 2001
> From: Lai Jiangshan <laijs@cn.fujitsu.com>
> Date: Sat, 15 Feb 2014 22:02:28 +0800
>
> When a kworker should die, the kworkre is notified through WORKER_DIE
> flag instead of kthread_should_stop(). This, IIRC, is primarily to
> keep the test synchronized inside worker_pool lock. WORKER_DIE is
> first set while holding pool->lock, the lock is dropped and
> kthread_stop() is called.
>
> Unfortunately, this means that there's a slight chance that the target
> kworker may see WORKER_DIE before kthread_stop() finishes and exits
> and frees the target task before or during kthread_stop().
>
> Fix it by pinning the target task before setting WORKER_DIE and
> putting it after kthread_stop() is done.
>
> tj: Improved patch description and comment. Moved pinning above
> WORKER_DIE for better signify what it's protecting.
>
> CC: stable@vger.kernel.org
I think no one hit this bug. So I add this stable TAG?
(Jason's bug-report drives me to review the workqueue harder,
and I found this possible bug, but I think it is irrespective
with Jason's bug-report.)
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> ---
> kernel/workqueue.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index 82ef9f3..193e977 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -1851,6 +1851,12 @@ static void destroy_worker(struct worker *worker)
> if (worker->flags & WORKER_IDLE)
> pool->nr_idle--;
>
> + /*
> + * Once WORKER_DIE is set, the kworker may destroy itself at any
> + * point. Pin to ensure the task stays until we're done with it.
> + */
> + get_task_struct(worker->task);
> +
> list_del_init(&worker->entry);
> worker->flags |= WORKER_DIE;
>
> @@ -1859,6 +1865,7 @@ static void destroy_worker(struct worker *worker)
> spin_unlock_irq(&pool->lock);
>
> kthread_stop(worker->task);
> + put_task_struct(worker->task);
> kfree(worker);
>
> spin_lock_irq(&pool->lock);
next prev parent reply other threads:[~2014-02-19 3:37 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-15 14:02 [PATCH] workqueue: ensure @task is valid across kthread_stop() Lai Jiangshan
[not found] ` <1392654243-2829-1-git-send-email-laijs@cn.fujitsu.com>
2014-02-17 16:24 ` [PATCH 1/3] workqueue: free worker earlier in worker_thread() Lai Jiangshan
2014-02-17 16:24 ` [PATCH 2/3] workqueue: async worker destruction Lai Jiangshan
2014-02-18 22:29 ` Tejun Heo
2014-02-17 16:24 ` [PATCH 3/3] workqueue: kick worker to die directly in idle timeout handler Lai Jiangshan
2014-02-18 22:31 ` Tejun Heo
2014-02-18 1:39 ` [PATCH 0/3] workqueue: async worker destruction Lai Jiangshan
2014-02-18 21:37 ` [PATCH wq/for-3.14-fixes] workqueue: ensure @task is valid across kthread_stop() Tejun Heo
2014-02-19 3:39 ` Lai Jiangshan [this message]
2014-02-19 3:39 ` Lai Jiangshan
2014-02-20 0:13 ` Tejun Heo
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=5304277E.4040705@cn.fujitsu.com \
--to=laijs@cn.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=tj@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.