OSDN Git Service

x86/uaccess: Don't leak the AC flags into __get_user() argument evaluation
[android-x86/kernel.git] / kernel / padata.c
index 7848f05..63449fc 100644 (file)
@@ -190,19 +190,20 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd)
 
        reorder = &next_queue->reorder;
 
+       spin_lock(&reorder->lock);
        if (!list_empty(&reorder->list)) {
                padata = list_entry(reorder->list.next,
                                    struct padata_priv, list);
 
-               spin_lock(&reorder->lock);
                list_del_init(&padata->list);
                atomic_dec(&pd->reorder_objects);
-               spin_unlock(&reorder->lock);
 
                pd->processed++;
 
+               spin_unlock(&reorder->lock);
                goto out;
        }
+       spin_unlock(&reorder->lock);
 
        if (__this_cpu_read(pd->pqueue->cpu_index) == next_queue->cpu_index) {
                padata = ERR_PTR(-ENODATA);
@@ -273,7 +274,12 @@ static void padata_reorder(struct parallel_data *pd)
         * The next object that needs serialization might have arrived to
         * the reorder queues in the meantime, we will be called again
         * from the timer function if no one else cares for it.
+        *
+        * Ensure reorder_objects is read after pd->lock is dropped so we see
+        * an increment from another task in padata_do_serial.  Pairs with
+        * smp_mb__after_atomic in padata_do_serial.
         */
+       smp_mb();
        if (atomic_read(&pd->reorder_objects)
                        && !(pinst->flags & PADATA_RESET))
                mod_timer(&pd->timer, jiffies + HZ);
@@ -342,6 +348,13 @@ void padata_do_serial(struct padata_priv *padata)
        list_add_tail(&padata->list, &pqueue->reorder.list);
        spin_unlock(&pqueue->reorder.lock);
 
+       /*
+        * Ensure the atomic_inc of reorder_objects above is ordered correctly
+        * with the trylock of pd->lock in padata_reorder.  Pairs with smp_mb
+        * in padata_reorder.
+        */
+       smp_mb__after_atomic();
+
        put_cpu();
 
        padata_reorder(pd);
@@ -357,7 +370,7 @@ static int padata_setup_cpumasks(struct parallel_data *pd,
 
        cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask);
        if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
-               free_cpumask_var(pd->cpumask.cbcpu);
+               free_cpumask_var(pd->cpumask.pcpu);
                return -ENOMEM;
        }