From: Tejun Heo <tj@kernel.org>
To: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] workqueue: fix leak of active
Date: Mon, 17 Sep 2012 11:56:20 -0700 [thread overview]
Message-ID: <20120917185620.GH18677@google.com> (raw)
In-Reply-To: <50568D85.5030309@cn.fujitsu.com>
Hello, Lai.
On Mon, Sep 17, 2012 at 10:40:05AM +0800, Lai Jiangshan wrote:
> try_to_grab_pending() leave LINKED tagalong in delayed queue when
> it deletes a work. This behavior will cause future
> cwq_activate_first_delayed() increase the ->nr_active wrongly,
> and may cause the whole cwq frozen.
>
> example:
>
> state: cwq->max_active = 1, cwq->nr_active = 1
> one work in cwq->pool, many in cwq->delayed_works.
>
> step1: try_to_grab_pending() remove a work from delayed_works but leave tagalong.
> step2: when the work in cwq->pool is finished, cwq_activate_first_delayed()
> move the tagalong to cwq->pool and increase the ->nr_active.
>
> current state: cwq->nr_active = 1, but works of the cwq in cwq->pool are all NO_COLOR,
> so even when these works are finished, cwq->nr_active will not be decreased,
> and no work will be moved from cwq->delayed_works. the cwq is frozen.
>
> Fix it by moving the tagalong to cwq->pool in try_to_grab_pending().
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Nice spotting.
> @@ -1101,11 +1101,26 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork,
> */
> smp_rmb();
> if (gcwq == get_work_gcwq(work)) {
> + unsigned long delayed;
> +
> + /*
> + * move LINKED tagalong(if exist) out from
> + * delayed queue. Otherwise some future
> + * cwq_activate_first_delayed() may move
> + * works(which are all NO_COLOR) to cwq->pool
> + * and increase the ->nr_active. It may
> + * cause the whole cwq frozen.
> + */
> + delayed = *work_data_bits(work) & WORK_STRUCT_DELAYED;
> + if (delayed)
> + move_linked_works(work,
> + &get_work_cwq(work)->pool->worklist,
> + NULL);
> +
> debug_work_deactivate(work);
> list_del_init(&work->entry);
> cwq_dec_nr_in_flight(get_work_cwq(work),
> - get_work_color(work),
> - *work_data_bits(work) & WORK_STRUCT_DELAYED);
> + get_work_color(work), delayed);
I'm a bit uneasy about how this introduces something which is on
active list but not quite active. Can we first activate it and then
grab its pending? IOW, change cwq_activate_first_delayed() to
cwq_activate_delayed() which takes @work instead and then call it with
the work item being grabbed in try_to_grab_pending() before dec'ing
nr_in_flight?
Thanks.
--
tejun
prev parent reply other threads:[~2012-09-17 18:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-17 2:40 [PATCH] workqueue: fix leak of active Lai Jiangshan
2012-09-17 18:56 ` Tejun Heo [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=20120917185620.GH18677@google.com \
--to=tj@kernel.org \
--cc=laijs@cn.fujitsu.com \
--cc=linux-kernel@vger.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.