diff options
-rw-r--r-- | kernel/workqueue.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 79a11e40f311..c11edc9c9365 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -186,6 +186,27 @@ struct wq_flusher { | |||
186 | }; | 186 | }; |
187 | 187 | ||
188 | /* | 188 | /* |
189 | * All cpumasks are assumed to be always set on UP and thus can't be | ||
190 | * used to determine whether there's something to be done. | ||
191 | */ | ||
192 | #ifdef CONFIG_SMP | ||
193 | typedef cpumask_var_t mayday_mask_t; | ||
194 | #define mayday_test_and_set_cpu(cpu, mask) \ | ||
195 | cpumask_test_and_set_cpu((cpu), (mask)) | ||
196 | #define mayday_clear_cpu(cpu, mask) cpumask_clear_cpu((cpu), (mask)) | ||
197 | #define for_each_mayday_cpu(cpu, mask) for_each_cpu((cpu), (mask)) | ||
198 | #define alloc_mayday_mask(maskp, gfp) alloc_cpumask_var((maskp), (gfp)) | ||
199 | #define free_mayday_mask(mask) free_cpumask_var((mask)) | ||
200 | #else | ||
201 | typedef unsigned long mayday_mask_t; | ||
202 | #define mayday_test_and_set_cpu(cpu, mask) test_and_set_bit(0, &(mask)) | ||
203 | #define mayday_clear_cpu(cpu, mask) clear_bit(0, &(mask)) | ||
204 | #define for_each_mayday_cpu(cpu, mask) if ((cpu) = 0, (mask)) | ||
205 | #define alloc_mayday_mask(maskp, gfp) true | ||
206 | #define free_mayday_mask(mask) do { } while (0) | ||
207 | #endif | ||
208 | |||
209 | /* | ||
189 | * The externally visible workqueue abstraction is an array of | 210 | * The externally visible workqueue abstraction is an array of |
190 | * per-CPU workqueues: | 211 | * per-CPU workqueues: |
191 | */ | 212 | */ |
@@ -206,7 +227,7 @@ struct workqueue_struct { | |||
206 | struct list_head flusher_queue; /* F: flush waiters */ | 227 | struct list_head flusher_queue; /* F: flush waiters */ |
207 | struct list_head flusher_overflow; /* F: flush overflow list */ | 228 | struct list_head flusher_overflow; /* F: flush overflow list */ |
208 | 229 | ||
209 | cpumask_var_t mayday_mask; /* cpus requesting rescue */ | 230 | mayday_mask_t mayday_mask; /* cpus requesting rescue */ |
210 | struct worker *rescuer; /* I: rescue worker */ | 231 | struct worker *rescuer; /* I: rescue worker */ |
211 | 232 | ||
212 | int saved_max_active; /* W: saved cwq max_active */ | 233 | int saved_max_active; /* W: saved cwq max_active */ |
@@ -1387,7 +1408,7 @@ static bool send_mayday(struct work_struct *work) | |||
1387 | /* WORK_CPU_UNBOUND can't be set in cpumask, use cpu 0 instead */ | 1408 | /* WORK_CPU_UNBOUND can't be set in cpumask, use cpu 0 instead */ |
1388 | if (cpu == WORK_CPU_UNBOUND) | 1409 | if (cpu == WORK_CPU_UNBOUND) |
1389 | cpu = 0; | 1410 | cpu = 0; |
1390 | if (!cpumask_test_and_set_cpu(cpu, wq->mayday_mask)) | 1411 | if (!mayday_test_and_set_cpu(cpu, wq->mayday_mask)) |
1391 | wake_up_process(wq->rescuer->task); | 1412 | wake_up_process(wq->rescuer->task); |
1392 | return true; | 1413 | return true; |
1393 | } | 1414 | } |
@@ -1915,14 +1936,14 @@ repeat: | |||
1915 | * See whether any cpu is asking for help. Unbounded | 1936 | * See whether any cpu is asking for help. Unbounded |
1916 | * workqueues use cpu 0 in mayday_mask for CPU_UNBOUND. | 1937 | * workqueues use cpu 0 in mayday_mask for CPU_UNBOUND. |
1917 | */ | 1938 | */ |
1918 | for_each_cpu(cpu, wq->mayday_mask) { | 1939 | for_each_mayday_cpu(cpu, wq->mayday_mask) { |
1919 | unsigned int tcpu = is_unbound ? WORK_CPU_UNBOUND : cpu; | 1940 | unsigned int tcpu = is_unbound ? WORK_CPU_UNBOUND : cpu; |
1920 | struct cpu_workqueue_struct *cwq = get_cwq(tcpu, wq); | 1941 | struct cpu_workqueue_struct *cwq = get_cwq(tcpu, wq); |
1921 | struct global_cwq *gcwq = cwq->gcwq; | 1942 | struct global_cwq *gcwq = cwq->gcwq; |
1922 | struct work_struct *work, *n; | 1943 | struct work_struct *work, *n; |
1923 | 1944 | ||
1924 | __set_current_state(TASK_RUNNING); | 1945 | __set_current_state(TASK_RUNNING); |
1925 | cpumask_clear_cpu(cpu, wq->mayday_mask); | 1946 | mayday_clear_cpu(cpu, wq->mayday_mask); |
1926 | 1947 | ||
1927 | /* migrate to the target cpu if possible */ | 1948 | /* migrate to the target cpu if possible */ |
1928 | rescuer->gcwq = gcwq; | 1949 | rescuer->gcwq = gcwq; |
@@ -2724,7 +2745,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, | |||
2724 | if (flags & WQ_RESCUER) { | 2745 | if (flags & WQ_RESCUER) { |
2725 | struct worker *rescuer; | 2746 | struct worker *rescuer; |
2726 | 2747 | ||
2727 | if (!alloc_cpumask_var(&wq->mayday_mask, GFP_KERNEL)) | 2748 | if (!alloc_mayday_mask(&wq->mayday_mask, GFP_KERNEL)) |
2728 | goto err; | 2749 | goto err; |
2729 | 2750 | ||
2730 | wq->rescuer = rescuer = alloc_worker(); | 2751 | wq->rescuer = rescuer = alloc_worker(); |
@@ -2759,7 +2780,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, | |||
2759 | err: | 2780 | err: |
2760 | if (wq) { | 2781 | if (wq) { |
2761 | free_cwqs(wq); | 2782 | free_cwqs(wq); |
2762 | free_cpumask_var(wq->mayday_mask); | 2783 | free_mayday_mask(wq->mayday_mask); |
2763 | kfree(wq->rescuer); | 2784 | kfree(wq->rescuer); |
2764 | kfree(wq); | 2785 | kfree(wq); |
2765 | } | 2786 | } |
@@ -2800,7 +2821,7 @@ void destroy_workqueue(struct workqueue_struct *wq) | |||
2800 | 2821 | ||
2801 | if (wq->flags & WQ_RESCUER) { | 2822 | if (wq->flags & WQ_RESCUER) { |
2802 | kthread_stop(wq->rescuer->task); | 2823 | kthread_stop(wq->rescuer->task); |
2803 | free_cpumask_var(wq->mayday_mask); | 2824 | free_mayday_mask(wq->mayday_mask); |
2804 | } | 2825 | } |
2805 | 2826 | ||
2806 | free_cwqs(wq); | 2827 | free_cwqs(wq); |