diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2011-09-30 11:57:58 +0200 |
|---|---|---|
| committer | Clark Williams <williams@redhat.com> | 2012-01-16 13:00:32 -0600 |
| commit | cd869b3ac4e255c990a57fd7e5b1738feaa2d3bd (patch) | |
| tree | ea11fbe460b68d886ce08927362176a1d35c3b99 /include/linux/cpu.h | |
| parent | 51de86faa6b5a70385b1b810ddbbeaa0d5dabacb (diff) | |
workqueue: Fix cpuhotplug trainwreck
The current workqueue code does crazy stuff on cpu unplug, it relies on
forced affine breakage, thereby violating per-cpu expectations. Worse,
it tries to re-attach to a cpu if the thing comes up again before all
previously queued works are finished. This breaks (admittedly bonkers)
cpu-hotplug use that relies on a down-up cycle to push all usage away.
Introduce a new WQ_NON_AFFINE flag that indicates a per-cpu workqueue
will not respect cpu affinity and use this to migrate all its pending
works to whatever cpu is doing cpu-down.
This also adds a warning for queue_on_cpu() users which warns when its
used on WQ_NON_AFFINE workqueues for the API implies you care about
what cpu things are ran on when such workqueues cannot guarantee this.
For the rest, simply flush all per-cpu works and don't mess about.
This also means that currently all workqueues that are manually
flushing things on cpu-down in order to provide the per-cpu guarantee
no longer need to do so.
In short, we tell the WQ what we want it to do, provide validation for
this and loose ~250 lines of code.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux/cpu.h')
| -rw-r--r-- | include/linux/cpu.h | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index c46ec3ecd661..72e90bbf625a 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -66,8 +66,10 @@ enum { /* migration should happen before other stuff but after perf */ CPU_PRI_PERF = 20, CPU_PRI_MIGRATION = 10, - /* prepare workqueues for other notifiers */ - CPU_PRI_WORKQUEUE = 5, + + CPU_PRI_WORKQUEUE_ACTIVE = 5, /* prepare workqueues for others */ + CPU_PRI_NORMAL = 0, + CPU_PRI_WORKQUEUE_INACTIVE = -5, /* flush workqueues after others */ }; #define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */ |
