On Wed, Jan 22, 2020 at 06:04:56PM +0100, Peter Zijlstra wrote: > +/* > + * cna_splice_head -- splice the entire secondary queue onto the head of the > + * primary queue. > + */ > +static cna_splice_head(struct qspinlock *lock, u32 val, > + struct mcs_spinlock *node, struct mcs_spinlock *next) > +{ > + struct mcs_spinlock *head_2nd, *tail_2nd; > + > + tail_2nd = decode_tail(node->locked); > + head_2nd = tail_2nd->next; > + > + if (lock) { That should be: if (!next) { > + u32 new = ((struct cna_node *)tail_2nd)->encoded_tail | _Q_LOCKED_VAL; > + if (!atomic_try_cmpxchg_relaxed(&lock->val, &val, new)) > + return NULL; > + > + /* > + * The moment we've linked the primary tail we can race with > + * the WRITE_ONCE(prev->next, node) store from new waiters. > + * That store must win. > + */ And that still is a shit comment; I'll go try again. > + cmpxchg_relaxed(&tail_2nd->next, head_2nd, next); > + } else { > + tail_2nd->next = next; > + } > + > + return head_2nd; > +}