diff options
authorOleg Nesterov <>2009-09-05 11:17:06 -0700
committerLinus Torvalds <>2009-09-05 11:30:42 -0700
commit4e49627b9bc29a14b393c480e8c979e3bc922ef7 (patch)
parent37d0892c5a94e208cf863e3b7bac014edee4346d (diff)
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 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 <> Cc: Dmitry Torokhov <> Cc: Roland Dreier <> Cc: Stefan Richter <> Signed-off-by: Andrew Morton <> Signed-off-by: Linus Torvalds <>
1 files changed, 15 insertions, 0 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 13e1adf55c4..6273fa97b52 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -240,6 +240,21 @@ static inline int cancel_delayed_work(struct delayed_work *work)
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);
/* Obsolete. use cancel_delayed_work_sync() */