|
@@ -3644,6 +3644,41 @@ err_destroy:
|
|
return NOTIFY_BAD;
|
|
return NOTIFY_BAD;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Workqueues should be brought up before normal priority CPU notifiers.
|
|
|
|
+ * This will be registered high priority CPU notifier.
|
|
|
|
+ */
|
|
|
|
+static int __devinit workqueue_cpu_up_callback(struct notifier_block *nfb,
|
|
|
|
+ unsigned long action,
|
|
|
|
+ void *hcpu)
|
|
|
|
+{
|
|
|
|
+ switch (action & ~CPU_TASKS_FROZEN) {
|
|
|
|
+ case CPU_UP_PREPARE:
|
|
|
|
+ case CPU_UP_CANCELED:
|
|
|
|
+ case CPU_DOWN_FAILED:
|
|
|
|
+ case CPU_ONLINE:
|
|
|
|
+ return workqueue_cpu_callback(nfb, action, hcpu);
|
|
|
|
+ }
|
|
|
|
+ return NOTIFY_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Workqueues should be brought down after normal priority CPU notifiers.
|
|
|
|
+ * This will be registered as low priority CPU notifier.
|
|
|
|
+ */
|
|
|
|
+static int __devinit workqueue_cpu_down_callback(struct notifier_block *nfb,
|
|
|
|
+ unsigned long action,
|
|
|
|
+ void *hcpu)
|
|
|
|
+{
|
|
|
|
+ switch (action & ~CPU_TASKS_FROZEN) {
|
|
|
|
+ case CPU_DOWN_PREPARE:
|
|
|
|
+ case CPU_DYING:
|
|
|
|
+ case CPU_POST_DEAD:
|
|
|
|
+ return workqueue_cpu_callback(nfb, action, hcpu);
|
|
|
|
+ }
|
|
|
|
+ return NOTIFY_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
#ifdef CONFIG_SMP
|
|
#ifdef CONFIG_SMP
|
|
|
|
|
|
struct work_for_cpu {
|
|
struct work_for_cpu {
|
|
@@ -3839,7 +3874,8 @@ static int __init init_workqueues(void)
|
|
unsigned int cpu;
|
|
unsigned int cpu;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- cpu_notifier(workqueue_cpu_callback, CPU_PRI_WORKQUEUE);
|
|
|
|
|
|
+ cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
|
|
|
|
+ cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
|
|
|
|
|
|
/* initialize gcwqs */
|
|
/* initialize gcwqs */
|
|
for_each_gcwq_cpu(cpu) {
|
|
for_each_gcwq_cpu(cpu) {
|