[WORKQUEUE]: cancel_delayed_work: use del_timer() instead of del_timer_sync()
authorOleg Nesterov <oleg@tv-sign.ru>
Thu, 26 Apr 2007 22:45:32 +0000 (15:45 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Apr 2007 22:45:32 +0000 (15:45 -0700)
commit071b638689464c6b39407025eedd810d5b5e6f5d
tree702b28d1a7acdd7ea904cd442c4491a24b93c059
parent566ec03448052c096dc3982fbe573522dc0ba479
[WORKQUEUE]: cancel_delayed_work: use del_timer() instead of del_timer_sync()

del_timer_sync() buys nothing for cancel_delayed_work(), but it is less
efficient since it locks the timer unconditionally, and may wait for the
completion of the delayed_work_timer_fn().

cancel_delayed_work() == 0 means:

before this patch:
work->func may still be running or queued

after this patch:
work->func may still be running or queued, or
delayed_work_timer_fn->__queue_work() in progress.

The latter doesn't differ from the caller's POV,
delayed_work_timer_fn() is called with _PENDING
bit set.

cancel_delayed_work() == 1 with this patch adds a new possibility:

delayed_work->work was cancelled, but delayed_work_timer_fn
is still running (this is only possible for the re-arming
works on single-threaded workqueue).

In this case the timer was re-started by work->func(), nobody
else can do this. This in turn means that delayed_work_timer_fn
has already passed __queue_work() (and wont't touch delayed_work)
because nobody else can queue delayed_work->work.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/workqueue.h