aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/workqueue.c26
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
89static
90struct 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 */
143int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) 151int 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}
157EXPORT_SYMBOL_GPL(queue_work); 163EXPORT_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;