Backported some 2.6.32 IB bug fixes to the 2.6.30 kernel.
[mirror/scst/.git] / srpt / patches / kernel-2.6.30-4e49627b9bc29a14b393c480e8c979e3bc922ef7-introduce-__cancel_delayed_work.patch
1 This patch was introduced in kernel 2.6.31 with the following description:
2
3 commit 4e49627b9bc29a14b393c480e8c979e3bc922ef7
4 Author: Oleg Nesterov <oleg@redhat.com>
5 Date:   Sat Sep 5 11:17:06 2009 -0700
6
7     workqueues: introduce __cancel_delayed_work()
8
9     cancel_delayed_work() has to use del_timer_sync() to guarantee the timer
10     function is not running after return.  But most users doesn't actually
11     need this, and del_timer_sync() has problems: it is not useable from
12     interrupt, and it depends on every lock which could be taken from irq.
13
14     Introduce __cancel_delayed_work() which calls del_timer() instead.
15
16     The immediate reason for this patch is
17     http://bugzilla.kernel.org/show_bug.cgi?id=13757
18     but hopefully this helper makes sense anyway.
19
20     As for 13757 bug, actually we need requeue_delayed_work(), but its
21     semantics are not yet clear.
22
23     Merge this patch early to resolves cross-tree interdependencies between
24     input and infiniband.
25
26     Signed-off-by: Oleg Nesterov <oleg@redhat.com>
27     Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
28     Cc: Roland Dreier <rdreier@cisco.com>
29     Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
30     Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
31     Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
32
33 ---
34
35 diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
36 index 13e1adf..6273fa9 100644
37 --- a/include/linux/workqueue.h
38 +++ b/include/linux/workqueue.h
39 @@ -240,6 +240,21 @@ static inline int cancel_delayed_work(struct delayed_work *work)
40         return ret;
41  }
42  
43 +/*
44 + * Like above, but uses del_timer() instead of del_timer_sync(). This means,
45 + * if it returns 0 the timer function may be running and the queueing is in
46 + * progress.
47 + */
48 +static inline int __cancel_delayed_work(struct delayed_work *work)
49 +{
50 +       int ret;
51 +
52 +       ret = del_timer(&work->timer);
53 +       if (ret)
54 +               work_clear_pending(&work->work);
55 +       return ret;
56 +}
57 +
58  extern int cancel_delayed_work_sync(struct delayed_work *work);
59  
60  /* Obsolete. use cancel_delayed_work_sync() */