|
@@ -408,14 +408,15 @@ queue:
|
|
*/
|
|
*/
|
|
if (old & _Q_TAIL_MASK) {
|
|
if (old & _Q_TAIL_MASK) {
|
|
prev = decode_tail(old);
|
|
prev = decode_tail(old);
|
|
|
|
+
|
|
/*
|
|
/*
|
|
- * The above xchg_tail() is also a load of @lock which
|
|
|
|
- * generates, through decode_tail(), a pointer. The address
|
|
|
|
- * dependency matches the RELEASE of xchg_tail() such that
|
|
|
|
- * the subsequent access to @prev happens after.
|
|
|
|
|
|
+ * We must ensure that the stores to @node are observed before
|
|
|
|
+ * the write to prev->next. The address dependency from
|
|
|
|
+ * xchg_tail is not sufficient to ensure this because the read
|
|
|
|
+ * component of xchg_tail is unordered with respect to the
|
|
|
|
+ * initialisation of @node.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
- WRITE_ONCE(prev->next, node);
|
|
|
|
|
|
+ smp_store_release(&prev->next, node);
|
|
|
|
|
|
pv_wait_node(node, prev);
|
|
pv_wait_node(node, prev);
|
|
arch_mcs_spin_lock_contended(&node->locked);
|
|
arch_mcs_spin_lock_contended(&node->locked);
|