aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cpu.h5
-rw-r--r--kernel/workqueue.c38
2 files changed, 40 insertions, 3 deletions
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 2e9b9ebbeb78..ce7a074f2519 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -73,8 +73,9 @@ enum {
73 /* migration should happen before other stuff but after perf */ 73 /* migration should happen before other stuff but after perf */
74 CPU_PRI_PERF = 20, 74 CPU_PRI_PERF = 20,
75 CPU_PRI_MIGRATION = 10, 75 CPU_PRI_MIGRATION = 10,
76 /* prepare workqueues for other notifiers */ 76 /* bring up workqueues before normal notifiers and down after */
77 CPU_PRI_WORKQUEUE = 5, 77 CPU_PRI_WORKQUEUE_UP = 5,
78 CPU_PRI_WORKQUEUE_DOWN = -5,
78}; 79};
79 80
80#define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */ 81#define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 4fa9e3552f1e..f59b7fd26e26 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3644,6 +3644,41 @@ err_destroy:
3644 return NOTIFY_BAD; 3644 return NOTIFY_BAD;
3645} 3645}
3646 3646
3647/*
3648 * Workqueues should be brought up before normal priority CPU notifiers.
3649 * This will be registered high priority CPU notifier.
3650 */
3651static int __devinit workqueue_cpu_up_callback(struct notifier_block *nfb,
3652 unsigned long action,
3653 void *hcpu)
3654{
3655 switch (action & ~CPU_TASKS_FROZEN) {
3656 case CPU_UP_PREPARE:
3657 case CPU_UP_CANCELED:
3658 case CPU_DOWN_FAILED:
3659 case CPU_ONLINE:
3660 return workqueue_cpu_callback(nfb, action, hcpu);
3661 }
3662 return NOTIFY_OK;
3663}
3664
3665/*
3666 * Workqueues should be brought down after normal priority CPU notifiers.
3667 * This will be registered as low priority CPU notifier.
3668 */
3669static int __devinit workqueue_cpu_down_callback(struct notifier_block *nfb,
3670 unsigned long action,
3671 void *hcpu)
3672{
3673 switch (action & ~CPU_TASKS_FROZEN) {
3674 case CPU_DOWN_PREPARE:
3675 case CPU_DYING:
3676 case CPU_POST_DEAD:
3677 return workqueue_cpu_callback(nfb, action, hcpu);
3678 }
3679 return NOTIFY_OK;
3680}
3681
3647#ifdef CONFIG_SMP 3682#ifdef CONFIG_SMP
3648 3683
3649struct work_for_cpu { 3684struct work_for_cpu {
@@ -3839,7 +3874,8 @@ static int __init init_workqueues(void)
3839 unsigned int cpu; 3874 unsigned int cpu;
3840 int i; 3875 int i;
3841 3876
3842 cpu_notifier(workqueue_cpu_callback, CPU_PRI_WORKQUEUE); 3877 cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
3878 cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
3843 3879
3844 /* initialize gcwqs */ 3880 /* initialize gcwqs */
3845 for_each_gcwq_cpu(cpu) { 3881 for_each_gcwq_cpu(cpu) {