From: Jarek Poplawski <jarkao2@o2.pl>
To: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Andrew Morton <akpm@linux-foundation.org>,
David Chinner <dgc@sgi.com>, David Howells <dhowells@redhat.com>,
Gautham Shenoy <ego@in.ibm.com>, Ingo Molnar <mingo@elte.hu>,
Srivatsa Vaddagiri <vatsa@in.ibm.com>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] make cancel_rearming_delayed_work() reliable
Date: Tue, 8 May 2007 09:15:44 +0200 [thread overview]
Message-ID: <20070508071544.GA1772@ff.dom.local> (raw)
In-Reply-To: <20070503204226.GA212@tv-sign.ru>
Hi,
Below are some of my suggestions:
On Fri, May 04, 2007 at 12:42:26AM +0400, Oleg Nesterov wrote:
...
> --- OLD/kernel/workqueue.c~1_CRDW 2007-05-02 23:29:07.000000000 +0400
> +++ OLD/kernel/workqueue.c 2007-05-03 22:42:29.000000000 +0400
> @@ -120,6 +120,11 @@ static void insert_work(struct cpu_workq
> struct work_struct *work, int tail)
> {
> set_wq_data(work, cwq);
> + /*
> + * Ensure that we get the right work->data if we see the
> + * result of list_add() below, see try_to_grab_pending().
> + */
> + smp_wmb();
> if (tail)
> list_add_tail(&work->entry, &cwq->worklist);
> else
> @@ -381,7 +386,46 @@ void fastcall flush_workqueue(struct wor
> }
> EXPORT_SYMBOL_GPL(flush_workqueue);
>
> -static void wait_on_work(struct cpu_workqueue_struct *cwq,
> +/*
> + * Upon a successfull return, the caller "owns" WORK_STRUCT_PENDING bit,
> + * so this work can't be re-armed in any way.
> + */
> +static int try_to_grab_pending(struct work_struct *work)
> +{
> + struct cpu_workqueue_struct *cwq;
> + int ret = 0;
> +
> + if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work)))
> + return 1;
Previous version used this check to run del_timer, and I think, it
was good idea. So, maybe, try something like this:
- run once del_timer before the loop (in cancel_rearming_ only),
- add a parmeter to try_to_grab_pending, e.g. "rearming",
- add here something like this:
else if (rearming && del_timer(&work->timer)
return 1;
> +
> + /*
> + * The queueing is in progress, or it is already queued. Try to
> + * steal it from ->worklist without clearing WORK_STRUCT_PENDING.
> + */
> +
> + cwq = get_wq_data(work);
> + if (!cwq)
> + return ret;
Probably you meant:
return 1;
BTW, probably there is some special reason it's in the loop now,
so maybe you should add a comment, why the old way (at the beginning
of a cancel_ function) is not enough.
I think adding the first check:
if (!list_empty(&work->entry)) {
without the lock is usable here.
> +
> + spin_lock_irq(&cwq->lock);
> + if (!list_empty(&work->entry)) {
> + /*
> + * This work is queued, but perhaps we locked the wrong cwq.
> + * In that case we must see the new value after rmb(), see
> + * insert_work()->wmb().
> + */
> + smp_rmb();
> + if (cwq == get_wq_data(work)) {
> + list_del_init(&work->entry);
> + ret = 1;
> + }
> + }
> + spin_unlock_irq(&cwq->lock);
> +
> + return ret;
> +}
> +
...
> +void cancel_work_sync(struct work_struct *work)
> +{
> + while (!try_to_grab_pending(work))
So this could be:
while (!try_to_grab_pending(work, 0))
> + ;
> + wait_on_work(work);
> + work_clear_pending(work);
> }
> EXPORT_SYMBOL_GPL(cancel_work_sync);
>
> +/**
> + * cancel_rearming_delayed_work - reliably kill off a delayed work.
> + * @dwork: the delayed work struct
> + *
> + * It is possible to use this function if dwork rearms itself via queue_work()
> + * or queue_delayed_work(). See also the comment for cancel_work_sync().
> + */
> +void cancel_rearming_delayed_work(struct delayed_work *dwork)
> +{
> + while (!del_timer(&dwork->timer) &&
> + !try_to_grab_pending(&dwork->work))
...and this like here:
if (!del_timer(&dwork->timer)
while (!try_to_grab_pending(&dwork->work, 1))
> + ;
> + wait_on_work(&dwork->work);
> + work_clear_pending(&dwork->work);
> +}
> +EXPORT_SYMBOL(cancel_rearming_delayed_work);
I didn't have as much time as needed, so I'll try to look
at this yet.
Cheers,
Jarek P.
next prev parent reply other threads:[~2007-05-08 7:09 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-03 20:42 [PATCH] make cancel_rearming_delayed_work() reliable Oleg Nesterov
2007-05-04 1:15 ` Andrew Morton
2007-05-04 17:09 ` Oleg Nesterov
2007-05-05 21:32 ` [PATCH] make-cancel_rearming_delayed_work-reliable-fix Oleg Nesterov
2007-05-07 10:31 ` Jarek Poplawski
2007-05-07 10:34 ` Oleg Nesterov
2007-05-07 11:55 ` Anton Vorontsov
2007-05-07 11:33 ` Oleg Nesterov
2007-05-08 9:16 ` Jarek Poplawski
2007-05-08 12:02 ` Oleg Nesterov
2007-05-08 13:07 ` Jarek Poplawski
2007-05-08 7:15 ` Jarek Poplawski [this message]
2007-05-08 12:31 ` [PATCH] make cancel_rearming_delayed_work() reliable Oleg Nesterov
2007-05-08 13:56 ` Jarek Poplawski
2007-05-08 14:05 ` Oleg Nesterov
2007-05-08 14:32 ` Jarek Poplawski
2007-05-08 14:12 ` Jarek Poplawski
2007-05-11 13:55 ` Tejun Heo
2007-05-11 13:47 ` Oleg Nesterov
2007-05-11 15:19 ` Tejun Heo
2007-05-11 14:53 ` Oleg Nesterov
2007-05-12 5:50 ` Tejun Heo
2007-05-13 19:27 ` Oleg Nesterov
2007-05-13 20:16 ` Tejun Heo
2007-05-13 21:25 ` Oleg Nesterov
2007-05-14 19:44 ` Oleg Nesterov
2007-05-15 8:26 ` Tejun Heo
2007-05-15 13:09 ` Jarek Poplawski
2007-05-15 22:08 ` Oleg Nesterov
2007-05-16 5:21 ` Jarek Poplawski
2007-05-15 22:00 ` Oleg Nesterov
2007-05-16 11:25 ` Tejun Heo
2007-05-16 18:52 ` Oleg Nesterov
2007-05-17 9:36 ` Tejun Heo
2007-05-18 7:35 ` Jarek Poplawski
2007-05-18 8:13 ` Jarek Poplawski
2007-05-18 13:33 ` Tejun Heo
2007-05-21 7:00 ` Jarek Poplawski
2007-05-21 8:59 ` Tejun Heo
2007-05-21 10:10 ` Jarek Poplawski
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=20070508071544.GA1772@ff.dom.local \
--to=jarkao2@o2.pl \
--cc=akpm@linux-foundation.org \
--cc=dgc@sgi.com \
--cc=dhowells@redhat.com \
--cc=ego@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oleg@tv-sign.ru \
--cc=vatsa@in.ibm.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.