workqueues: introduce __cancel_delayed_work()
cancel_delayed_work() has to use del_timer_sync() to guarantee the timer function is not running after return. But most users doesn't actually need this, and del_timer_sync() has problems: it is not useable from interrupt, and it depends on every lock which could be taken from irq. Introduce __cancel_delayed_work() which calls del_timer() instead. The immediate reason for this patch is http://bugzilla.kernel.org/show_bug.cgi?id=13757 but hopefully this helper makes sense anyway. As for 13757 bug, actually we need requeue_delayed_work(), but its semantics are not yet clear. Merge this patch early to resolves cross-tree interdependencies between input and infiniband. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> Cc: Roland Dreier <rdreier@cisco.com> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
37d0892c5a
commit
4e49627b9b
|
@ -240,6 +240,21 @@ static inline int cancel_delayed_work(struct delayed_work *work)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like above, but uses del_timer() instead of del_timer_sync(). This means,
|
||||||
|
* if it returns 0 the timer function may be running and the queueing is in
|
||||||
|
* progress.
|
||||||
|
*/
|
||||||
|
static inline int __cancel_delayed_work(struct delayed_work *work)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = del_timer(&work->timer);
|
||||||
|
if (ret)
|
||||||
|
work_clear_pending(&work->work);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
extern int cancel_delayed_work_sync(struct delayed_work *work);
|
extern int cancel_delayed_work_sync(struct delayed_work *work);
|
||||||
|
|
||||||
/* Obsolete. use cancel_delayed_work_sync() */
|
/* Obsolete. use cancel_delayed_work_sync() */
|
||||||
|
|
Loading…
Reference in New Issue