diff options
-rw-r--r-- | kernel/padata.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/kernel/padata.c b/kernel/padata.c index 2d2fddbb7a4c..15a8ad63f4ff 100644 --- a/kernel/padata.c +++ b/kernel/padata.c | |||
@@ -267,7 +267,12 @@ static void padata_reorder(struct parallel_data *pd) | |||
267 | * The next object that needs serialization might have arrived to | 267 | * The next object that needs serialization might have arrived to |
268 | * the reorder queues in the meantime, we will be called again | 268 | * the reorder queues in the meantime, we will be called again |
269 | * from the timer function if no one else cares for it. | 269 | * from the timer function if no one else cares for it. |
270 | * | ||
271 | * Ensure reorder_objects is read after pd->lock is dropped so we see | ||
272 | * an increment from another task in padata_do_serial. Pairs with | ||
273 | * smp_mb__after_atomic in padata_do_serial. | ||
270 | */ | 274 | */ |
275 | smp_mb(); | ||
271 | if (atomic_read(&pd->reorder_objects) | 276 | if (atomic_read(&pd->reorder_objects) |
272 | && !(pinst->flags & PADATA_RESET)) | 277 | && !(pinst->flags & PADATA_RESET)) |
273 | mod_timer(&pd->timer, jiffies + HZ); | 278 | mod_timer(&pd->timer, jiffies + HZ); |
@@ -387,6 +392,13 @@ void padata_do_serial(struct padata_priv *padata) | |||
387 | list_add_tail(&padata->list, &pqueue->reorder.list); | 392 | list_add_tail(&padata->list, &pqueue->reorder.list); |
388 | spin_unlock(&pqueue->reorder.lock); | 393 | spin_unlock(&pqueue->reorder.lock); |
389 | 394 | ||
395 | /* | ||
396 | * Ensure the atomic_inc of reorder_objects above is ordered correctly | ||
397 | * with the trylock of pd->lock in padata_reorder. Pairs with smp_mb | ||
398 | * in padata_reorder. | ||
399 | */ | ||
400 | smp_mb__after_atomic(); | ||
401 | |||
390 | put_cpu(); | 402 | put_cpu(); |
391 | 403 | ||
392 | /* If we're running on the wrong CPU, call padata_reorder() via a | 404 | /* If we're running on the wrong CPU, call padata_reorder() via a |