diff options
| author | Jens Axboe <jens.axboe@oracle.com> | 2010-05-21 15:27:26 -0400 |
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2010-05-21 15:27:26 -0400 |
| commit | ee9a3607fb03e804ddf624544105f4e34260c380 (patch) | |
| tree | ce41b6e0fa10982a306f6c142a92dbf3c9961284 /kernel/workqueue.c | |
| parent | b492e95be0ae672922f4734acf3f5d35c30be948 (diff) | |
| parent | d515e86e639890b33a09390d062b0831664f04a2 (diff) | |
Merge branch 'master' into for-2.6.35
Conflicts:
fs/ext3/fsync.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index dee48658805c..77dabbf64b8f 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -229,6 +229,16 @@ static inline void set_wq_data(struct work_struct *work, | |||
| 229 | atomic_long_set(&work->data, new); | 229 | atomic_long_set(&work->data, new); |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | /* | ||
| 233 | * Clear WORK_STRUCT_PENDING and the workqueue on which it was queued. | ||
| 234 | */ | ||
| 235 | static inline void clear_wq_data(struct work_struct *work) | ||
| 236 | { | ||
| 237 | unsigned long flags = *work_data_bits(work) & | ||
| 238 | (1UL << WORK_STRUCT_STATIC); | ||
| 239 | atomic_long_set(&work->data, flags); | ||
| 240 | } | ||
| 241 | |||
| 232 | static inline | 242 | static inline |
| 233 | struct cpu_workqueue_struct *get_wq_data(struct work_struct *work) | 243 | struct cpu_workqueue_struct *get_wq_data(struct work_struct *work) |
| 234 | { | 244 | { |
| @@ -671,7 +681,7 @@ static int __cancel_work_timer(struct work_struct *work, | |||
| 671 | wait_on_work(work); | 681 | wait_on_work(work); |
| 672 | } while (unlikely(ret < 0)); | 682 | } while (unlikely(ret < 0)); |
| 673 | 683 | ||
| 674 | work_clear_pending(work); | 684 | clear_wq_data(work); |
| 675 | return ret; | 685 | return ret; |
| 676 | } | 686 | } |
| 677 | 687 | ||
| @@ -774,7 +784,7 @@ void flush_delayed_work(struct delayed_work *dwork) | |||
| 774 | { | 784 | { |
| 775 | if (del_timer_sync(&dwork->timer)) { | 785 | if (del_timer_sync(&dwork->timer)) { |
| 776 | struct cpu_workqueue_struct *cwq; | 786 | struct cpu_workqueue_struct *cwq; |
| 777 | cwq = wq_per_cpu(keventd_wq, get_cpu()); | 787 | cwq = wq_per_cpu(get_wq_data(&dwork->work)->wq, get_cpu()); |
| 778 | __queue_work(cwq, &dwork->work); | 788 | __queue_work(cwq, &dwork->work); |
| 779 | put_cpu(); | 789 | put_cpu(); |
| 780 | } | 790 | } |
| @@ -845,6 +855,30 @@ int schedule_on_each_cpu(work_func_t func) | |||
| 845 | return 0; | 855 | return 0; |
| 846 | } | 856 | } |
| 847 | 857 | ||
| 858 | /** | ||
| 859 | * flush_scheduled_work - ensure that any scheduled work has run to completion. | ||
| 860 | * | ||
| 861 | * Forces execution of the kernel-global workqueue and blocks until its | ||
| 862 | * completion. | ||
| 863 | * | ||
| 864 | * Think twice before calling this function! It's very easy to get into | ||
| 865 | * trouble if you don't take great care. Either of the following situations | ||
| 866 | * will lead to deadlock: | ||
| 867 | * | ||
| 868 | * One of the work items currently on the workqueue needs to acquire | ||
| 869 | * a lock held by your code or its caller. | ||
| 870 | * | ||
| 871 | * Your code is running in the context of a work routine. | ||
| 872 | * | ||
| 873 | * They will be detected by lockdep when they occur, but the first might not | ||
| 874 | * occur very often. It depends on what work items are on the workqueue and | ||
| 875 | * what locks they need, which you have no control over. | ||
| 876 | * | ||
| 877 | * In most situations flushing the entire workqueue is overkill; you merely | ||
| 878 | * need to know that a particular work item isn't queued and isn't running. | ||
| 879 | * In such cases you should use cancel_delayed_work_sync() or | ||
| 880 | * cancel_work_sync() instead. | ||
| 881 | */ | ||
| 848 | void flush_scheduled_work(void) | 882 | void flush_scheduled_work(void) |
| 849 | { | 883 | { |
| 850 | flush_workqueue(keventd_wq); | 884 | flush_workqueue(keventd_wq); |
