diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2013-11-18 13:00:29 -0500 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-11-25 16:37:22 -0500 |
| commit | 12997d1a999cd1b22e21a238c96780f2a55e4e13 (patch) | |
| tree | 70470549b47f1a0d90861609c6ce8ca2d95e286e | |
| parent | 12c3156f10c5d8c5f1fb3f0bbdb8c1ddb1d1f65c (diff) | |
Revert "workqueue: allow work_on_cpu() to be called recursively"
This reverts commit c2fda509667b0fda4372a237f5a59ea4570b1627.
c2fda509667b removed lockdep annotation from work_on_cpu() to work around
the PCI path that calls work_on_cpu() from within a work_on_cpu() work item
(PF driver .probe() method -> pci_enable_sriov() -> add VFs -> VF driver
.probe method).
961da7fb6b22 ("PCI: Avoid unnecessary CPU switch when calling driver
.probe() method) avoids that recursive work_on_cpu() use in a different
way, so this revert restores the work_on_cpu() lockdep annotation.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Tejun Heo <tj@kernel.org>
| -rw-r--r-- | kernel/workqueue.c | 32 |
1 files changed, 10 insertions, 22 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 987293d03ebc..5690b8eabfbc 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -2840,19 +2840,6 @@ already_gone: | |||
| 2840 | return false; | 2840 | return false; |
| 2841 | } | 2841 | } |
| 2842 | 2842 | ||
| 2843 | static bool __flush_work(struct work_struct *work) | ||
| 2844 | { | ||
| 2845 | struct wq_barrier barr; | ||
| 2846 | |||
| 2847 | if (start_flush_work(work, &barr)) { | ||
| 2848 | wait_for_completion(&barr.done); | ||
| 2849 | destroy_work_on_stack(&barr.work); | ||
| 2850 | return true; | ||
| 2851 | } else { | ||
| 2852 | return false; | ||
| 2853 | } | ||
| 2854 | } | ||
| 2855 | |||
| 2856 | /** | 2843 | /** |
| 2857 | * flush_work - wait for a work to finish executing the last queueing instance | 2844 | * flush_work - wait for a work to finish executing the last queueing instance |
| 2858 | * @work: the work to flush | 2845 | * @work: the work to flush |
| @@ -2866,10 +2853,18 @@ static bool __flush_work(struct work_struct *work) | |||
| 2866 | */ | 2853 | */ |
| 2867 | bool flush_work(struct work_struct *work) | 2854 | bool flush_work(struct work_struct *work) |
| 2868 | { | 2855 | { |
| 2856 | struct wq_barrier barr; | ||
| 2857 | |||
| 2869 | lock_map_acquire(&work->lockdep_map); | 2858 | lock_map_acquire(&work->lockdep_map); |
| 2870 | lock_map_release(&work->lockdep_map); | 2859 | lock_map_release(&work->lockdep_map); |
| 2871 | 2860 | ||
| 2872 | return __flush_work(work); | 2861 | if (start_flush_work(work, &barr)) { |
| 2862 | wait_for_completion(&barr.done); | ||
| 2863 | destroy_work_on_stack(&barr.work); | ||
| 2864 | return true; | ||
| 2865 | } else { | ||
| 2866 | return false; | ||
| 2867 | } | ||
| 2873 | } | 2868 | } |
| 2874 | EXPORT_SYMBOL_GPL(flush_work); | 2869 | EXPORT_SYMBOL_GPL(flush_work); |
| 2875 | 2870 | ||
| @@ -4814,14 +4809,7 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg) | |||
| 4814 | 4809 | ||
| 4815 | INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); | 4810 | INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); |
| 4816 | schedule_work_on(cpu, &wfc.work); | 4811 | schedule_work_on(cpu, &wfc.work); |
| 4817 | 4812 | flush_work(&wfc.work); | |
| 4818 | /* | ||
| 4819 | * The work item is on-stack and can't lead to deadlock through | ||
| 4820 | * flushing. Use __flush_work() to avoid spurious lockdep warnings | ||
| 4821 | * when work_on_cpu()s are nested. | ||
| 4822 | */ | ||
| 4823 | __flush_work(&wfc.work); | ||
| 4824 | |||
| 4825 | return wfc.ret; | 4813 | return wfc.ret; |
| 4826 | } | 4814 | } |
| 4827 | EXPORT_SYMBOL_GPL(work_on_cpu); | 4815 | EXPORT_SYMBOL_GPL(work_on_cpu); |
