diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/workqueue.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0eb9b33f1d91..985902e2e071 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -86,6 +86,14 @@ static const cpumask_t *wq_cpu_map(struct workqueue_struct *wq) | |||
86 | ? &cpu_singlethread_map : &cpu_populated_map; | 86 | ? &cpu_singlethread_map : &cpu_populated_map; |
87 | } | 87 | } |
88 | 88 | ||
89 | static | ||
90 | struct cpu_workqueue_struct *wq_per_cpu(struct workqueue_struct *wq, int cpu) | ||
91 | { | ||
92 | if (unlikely(is_single_threaded(wq))) | ||
93 | cpu = singlethread_cpu; | ||
94 | return per_cpu_ptr(wq->cpu_wq, cpu); | ||
95 | } | ||
96 | |||
89 | /* | 97 | /* |
90 | * Set the workqueue on which a work item is to be run | 98 | * Set the workqueue on which a work item is to be run |
91 | * - Must *only* be called if the pending flag is set | 99 | * - Must *only* be called if the pending flag is set |
@@ -142,16 +150,14 @@ static void __queue_work(struct cpu_workqueue_struct *cwq, | |||
142 | */ | 150 | */ |
143 | int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) | 151 | int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) |
144 | { | 152 | { |
145 | int ret = 0, cpu = get_cpu(); | 153 | int ret = 0; |
146 | 154 | ||
147 | if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { | 155 | if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { |
148 | if (unlikely(is_single_threaded(wq))) | ||
149 | cpu = singlethread_cpu; | ||
150 | BUG_ON(!list_empty(&work->entry)); | 156 | BUG_ON(!list_empty(&work->entry)); |
151 | __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); | 157 | __queue_work(wq_per_cpu(wq, get_cpu()), work); |
158 | put_cpu(); | ||
152 | ret = 1; | 159 | ret = 1; |
153 | } | 160 | } |
154 | put_cpu(); | ||
155 | return ret; | 161 | return ret; |
156 | } | 162 | } |
157 | EXPORT_SYMBOL_GPL(queue_work); | 163 | EXPORT_SYMBOL_GPL(queue_work); |
@@ -161,12 +167,8 @@ void delayed_work_timer_fn(unsigned long __data) | |||
161 | struct delayed_work *dwork = (struct delayed_work *)__data; | 167 | struct delayed_work *dwork = (struct delayed_work *)__data; |
162 | struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work); | 168 | struct cpu_workqueue_struct *cwq = get_wq_data(&dwork->work); |
163 | struct workqueue_struct *wq = cwq->wq; | 169 | struct workqueue_struct *wq = cwq->wq; |
164 | int cpu = smp_processor_id(); | ||
165 | |||
166 | if (unlikely(is_single_threaded(wq))) | ||
167 | cpu = singlethread_cpu; | ||
168 | 170 | ||
169 | __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), &dwork->work); | 171 | __queue_work(wq_per_cpu(wq, smp_processor_id()), &dwork->work); |
170 | } | 172 | } |
171 | 173 | ||
172 | /** | 174 | /** |
@@ -209,9 +211,7 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | |||
209 | BUG_ON(!list_empty(&work->entry)); | 211 | BUG_ON(!list_empty(&work->entry)); |
210 | 212 | ||
211 | /* This stores cwq for the moment, for the timer_fn */ | 213 | /* This stores cwq for the moment, for the timer_fn */ |
212 | set_wq_data(work, | 214 | set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id())); |
213 | per_cpu_ptr(wq->cpu_wq, wq->singlethread ? | ||
214 | singlethread_cpu : raw_smp_processor_id())); | ||
215 | timer->expires = jiffies + delay; | 215 | timer->expires = jiffies + delay; |
216 | timer->data = (unsigned long)dwork; | 216 | timer->data = (unsigned long)dwork; |
217 | timer->function = delayed_work_timer_fn; | 217 | timer->function = delayed_work_timer_fn; |