diff options
| author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2013-08-15 18:00:46 -0700 |
|---|---|---|
| committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2013-08-15 18:00:46 -0700 |
| commit | 5845c13a70b40f1ce4dfe83acb7796bed8a60672 (patch) | |
| tree | 94408827a9da0a2e16cd189692cbb425345e92a8 /kernel/workqueue.c | |
| parent | 224563b6ce034b82f8511969d9496113da34fb2c (diff) | |
| parent | 52fb61250a7a132b0cfb9f4a1060a1f3c49e5a25 (diff) | |
Merge tag 'for-usb-2013-08-15-step-1' into for-usb-next
xhci: Step 1 to fix usb-linus and usb-next.
Hi Greg,
This is the first of three steps to fix your usb-linus and usb-next
trees. As I mentioned, commit 4fae6f0fa86f92e6bc7429371b1e177ad0aaac66
"USB: handle LPM errors during device suspend correctly" was incorrectly
added to usb-next when it should have been added to usb-linus and marked
for stable.
Two port power off bug fixes touch the same code that patch touches, but
it's not easy to simply move commit 4fae6f0f patch to usb-linus because
commit 28e861658e23ca94692f98e245d254c75c8088a7 "USB: refactor code for
enabling/disabling remote wakeup" also touched those code sections.
I propose a two step process to fix this:
1. Pull these four patches into usb-linus.
2. Revert commit 28e861658e23ca94692f98e245d254c75c8088a7 from usb-next.
Merge usb-linus into usb-next, and resolve the conflicts.
I will be sending pull requests for these steps.
This pull request is step one, and contains the backported version of
commit 4fae6f0fa86f92e6bc7429371b1e177ad0aaac66, the two port power off
fixes, and an unrelated xhci-plat bug fix.
Sarah Sharp
Resolved conflicts:
drivers/usb/core/hub.c
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0b72e816b8d0..7f5d4be22034 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2817,6 +2817,19 @@ already_gone: return false; } +static bool __flush_work(struct work_struct *work) +{ + struct wq_barrier barr; + + if (start_flush_work(work, &barr)) { + wait_for_completion(&barr.done); + destroy_work_on_stack(&barr.work); + return true; + } else { + return false; + } +} + /** * flush_work - wait for a work to finish executing the last queueing instance * @work: the work to flush @@ -2830,18 +2843,10 @@ already_gone: */ bool flush_work(struct work_struct *work) { - struct wq_barrier barr; - lock_map_acquire(&work->lockdep_map); lock_map_release(&work->lockdep_map); - if (start_flush_work(work, &barr)) { - wait_for_completion(&barr.done); - destroy_work_on_stack(&barr.work); - return true; - } else { - return false; - } + return __flush_work(work); } EXPORT_SYMBOL_GPL(flush_work); @@ -3411,6 +3416,12 @@ static void copy_workqueue_attrs(struct workqueue_attrs *to, { to->nice = from->nice; cpumask_copy(to->cpumask, from->cpumask); + /* + * Unlike hash and equality test, this function doesn't ignore + * ->no_numa as it is used for both pool and wq attrs. Instead, + * get_unbound_pool() explicitly clears ->no_numa after copying. + */ + to->no_numa = from->no_numa; } /* hash value of the content of @attr */ @@ -3578,6 +3589,12 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs) lockdep_set_subclass(&pool->lock, 1); /* see put_pwq() */ copy_workqueue_attrs(pool->attrs, attrs); + /* + * no_numa isn't a worker_pool attribute, always clear it. See + * 'struct workqueue_attrs' comments for detail. + */ + pool->attrs->no_numa = false; + /* if cpumask is contained inside a NUMA node, we belong to that node */ if (wq_numa_enabled) { for_each_node(node) { @@ -4756,7 +4773,14 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg) INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); schedule_work_on(cpu, &wfc.work); - flush_work(&wfc.work); + + /* + * The work item is on-stack and can't lead to deadlock through + * flushing. Use __flush_work() to avoid spurious lockdep warnings + * when work_on_cpu()s are nested. + */ + __flush_work(&wfc.work); + return wfc.ret; } EXPORT_SYMBOL_GPL(work_on_cpu); |
