void _rcu_lfs_push(struct rcu_lfs_stack *s, struct rcu_lfs_node *node)
{
+ struct rcu_lfs_node *head = NULL;
+
for (;;) {
- struct rcu_lfs_node *head;
+ struct rcu_lfs_node *old_head = head;
- rcu_read_lock();
- head = rcu_dereference(s->head);
node->next = head;
/*
* uatomic_cmpxchg() implicit memory barrier orders earlier
* stores to node before publication.
*/
- if (uatomic_cmpxchg(&s->head, head, node) == head) {
- rcu_read_unlock();
- return;
- } else {
- /* Failure to prepend. Retry. */
- rcu_read_unlock();
- continue;
- }
+ head = uatomic_cmpxchg(&s->head, old_head, node);
+ if (old_head == head)
+ break;
}
}