On Thu, May 05, 2016 at 08:44:04PM -0000, Thomas Gleixner wrote:
> +struct futex_hash {
> +     struct raw_spinlock             lock;

        raw_spinlock_t ?

> +     unsigned int                    hash_bits;
> +     struct futex_hash_bucket        *hash;
> +};

> +static void futex_populate_hash(unsigned int hash_bits)
> +{
> +     struct mm_struct *mm = current->mm;
> +     struct futex_hash_bucket *hb = NULL;
> +
> +     /*
> +      * We don't need an explicit smp_mb() when the hash is populated
> +      * because before we dereference mm->futex_hash.hash_bits in the hash
> +      * function we have an smp_mb() in futex_get_key_refs() already.
> +      */
> +     if (mm->futex_hash.hash)
> +             return;
> +
> +     /*
> +      * If we failed to allocate a hash on the fly, fall back to the global
> +      * hash.
> +      */
> +     hb = futex_alloc_hash(hash_bits);
> +     if (!hb)
> +             hb = FUTEX_USE_GLOBAL_HASH;
> +
> +     raw_spin_lock(&mm->futex_hash.lock);
> +     /* We might have raced with another task allocating the hash. */
> +     if (!mm->futex_hash.hash) {
> +             mm->futex_hash.hash_bits = hash_bits;
> +             /*
> +              * Ensure that the above is visible before we store
> +              * the pointer.
> +              */
> +             smp_wmb(); /* (A0) Pairs with (B) */
> +             mm->futex_hash.hash = hb;

                smp_store_release(&mm->futex_hash.hash, hb); ?

> +             hb = NULL;
> +     }
> +     raw_spin_unlock(&mm->futex_hash.lock);
> +     kfree(hb);
> +}

Reply via email to