Re: [PATCH 8/9] qspinlock: Generic paravirt support

From: Peter Zijlstra
Date: Thu Mar 19 2015 - 09:44:01 EST


On Thu, Mar 19, 2015 at 01:25:36PM +0100, Peter Zijlstra wrote:
> +static struct qspinlock **pv_hash(struct qspinlock *lock)
> +{
> + u32 hash = hash_ptr(lock, PV_LOCK_HASH_BITS);
> + struct pv_hash_bucket *hb, *end;
> +
> + if (!hash)
> + hash = 1;
> +
> + hb = &__pv_lock_hash[hash_align(hash)];
> + for (;;) {
> + for (end = hb + PV_HB_PER_LINE; hb < end; hb++) {
> + if (cmpxchg(&hb->lock, NULL, HB_RESERVED)) {

That should be: !cmpxchg(), bit disturbing that that booted.

> + WRITE_ONCE(hb->cpu, smp_processor_id());
> + /*
> + * Since we must read lock first and cpu
> + * second, we must write cpu first and lock
> + * second, therefore use HB_RESERVE to mark an
> + * entry in use before writing the values.
> + *
> + * This can cause hb_hash_find() to not find a
> + * cpu even though _Q_SLOW_VAL, this is not a
> + * problem since we re-check l->locked before
> + * going to sleep and the unlock will have
> + * cleared l->locked already.
> + */
> + smp_wmb(); /* matches rmb from pv_hash_find */
> + WRITE_ONCE(hb->lock, lock);
> + goto done;
> + }
> + }
> +
> + hash = lfsr(hash, PV_LOCK_HASH_BITS);
> + hb = &__pv_lock_hash[hash_align(hash)];
> + }
> +
> +done:
> + return &hb->lock;
> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/