diff options
Diffstat (limited to 'kernel/padata.c')
-rw-r--r-- | kernel/padata.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/kernel/padata.c b/kernel/padata.c index 82958e01564b..6d7ea481b716 100644 --- a/kernel/padata.c +++ b/kernel/padata.c | |||
@@ -231,7 +231,8 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd) | |||
231 | goto out; | 231 | goto out; |
232 | } | 232 | } |
233 | 233 | ||
234 | if (next_nr % num_cpus == next_queue->cpu_index) { | 234 | queue = per_cpu_ptr(pd->queue, smp_processor_id()); |
235 | if (queue->cpu_index == next_queue->cpu_index) { | ||
235 | padata = ERR_PTR(-ENODATA); | 236 | padata = ERR_PTR(-ENODATA); |
236 | goto out; | 237 | goto out; |
237 | } | 238 | } |
@@ -247,9 +248,8 @@ static void padata_reorder(struct parallel_data *pd) | |||
247 | struct padata_queue *queue; | 248 | struct padata_queue *queue; |
248 | struct padata_instance *pinst = pd->pinst; | 249 | struct padata_instance *pinst = pd->pinst; |
249 | 250 | ||
250 | try_again: | ||
251 | if (!spin_trylock_bh(&pd->lock)) | 251 | if (!spin_trylock_bh(&pd->lock)) |
252 | goto out; | 252 | return; |
253 | 253 | ||
254 | while (1) { | 254 | while (1) { |
255 | padata = padata_get_next(pd); | 255 | padata = padata_get_next(pd); |
@@ -258,8 +258,9 @@ try_again: | |||
258 | break; | 258 | break; |
259 | 259 | ||
260 | if (PTR_ERR(padata) == -ENODATA) { | 260 | if (PTR_ERR(padata) == -ENODATA) { |
261 | del_timer(&pd->timer); | ||
261 | spin_unlock_bh(&pd->lock); | 262 | spin_unlock_bh(&pd->lock); |
262 | goto out; | 263 | return; |
263 | } | 264 | } |
264 | 265 | ||
265 | queue = per_cpu_ptr(pd->queue, padata->cb_cpu); | 266 | queue = per_cpu_ptr(pd->queue, padata->cb_cpu); |
@@ -273,13 +274,22 @@ try_again: | |||
273 | 274 | ||
274 | spin_unlock_bh(&pd->lock); | 275 | spin_unlock_bh(&pd->lock); |
275 | 276 | ||
276 | if (atomic_read(&pd->reorder_objects)) | 277 | if (atomic_read(&pd->reorder_objects) |
277 | goto try_again; | 278 | && !(pinst->flags & PADATA_RESET)) |
279 | mod_timer(&pd->timer, jiffies + HZ); | ||
280 | else | ||
281 | del_timer(&pd->timer); | ||
278 | 282 | ||
279 | out: | ||
280 | return; | 283 | return; |
281 | } | 284 | } |
282 | 285 | ||
286 | static void padata_reorder_timer(unsigned long arg) | ||
287 | { | ||
288 | struct parallel_data *pd = (struct parallel_data *)arg; | ||
289 | |||
290 | padata_reorder(pd); | ||
291 | } | ||
292 | |||
283 | static void padata_serial_worker(struct work_struct *work) | 293 | static void padata_serial_worker(struct work_struct *work) |
284 | { | 294 | { |
285 | struct padata_queue *queue; | 295 | struct padata_queue *queue; |
@@ -383,6 +393,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_instance *pinst, | |||
383 | num_cpus = cpumask_weight(pd->cpumask); | 393 | num_cpus = cpumask_weight(pd->cpumask); |
384 | pd->max_seq_nr = (MAX_SEQ_NR / num_cpus) * num_cpus - 1; | 394 | pd->max_seq_nr = (MAX_SEQ_NR / num_cpus) * num_cpus - 1; |
385 | 395 | ||
396 | setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd); | ||
386 | atomic_set(&pd->seq_nr, -1); | 397 | atomic_set(&pd->seq_nr, -1); |
387 | atomic_set(&pd->reorder_objects, 0); | 398 | atomic_set(&pd->reorder_objects, 0); |
388 | atomic_set(&pd->refcnt, 0); | 399 | atomic_set(&pd->refcnt, 0); |