Skip to content

Commit 4f1d2a0

Browse files
ubizjakakpm00
authored andcommitted
llist: use try_cmpxchg in llist_add_batch and llist_del_first
Use try_cmpxchg instead of cmpxchg (*ptr, old, new) == old in llist_add_batch and llist_del_first. x86 CMPXCHG instruction returns success in ZF flag, so this change saves a compare after cmpxchg. Also, try_cmpxchg implicitly assigns old *ptr value to "old" when cmpxchg fails, enabling further code simplifications. No functional change intended. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Uros Bizjak <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 05c6257 commit 4f1d2a0

File tree

1 file changed

+4
-8
lines changed

1 file changed

+4
-8
lines changed

lib/llist.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,
3030

3131
do {
3232
new_last->next = first = READ_ONCE(head->first);
33-
} while (cmpxchg(&head->first, first, new_first) != first);
33+
} while (!try_cmpxchg(&head->first, &first, new_first));
3434

3535
return !first;
3636
}
@@ -52,18 +52,14 @@ EXPORT_SYMBOL_GPL(llist_add_batch);
5252
*/
5353
struct llist_node *llist_del_first(struct llist_head *head)
5454
{
55-
struct llist_node *entry, *old_entry, *next;
55+
struct llist_node *entry, *next;
5656

5757
entry = smp_load_acquire(&head->first);
58-
for (;;) {
58+
do {
5959
if (entry == NULL)
6060
return NULL;
61-
old_entry = entry;
6261
next = READ_ONCE(entry->next);
63-
entry = cmpxchg(&head->first, old_entry, next);
64-
if (entry == old_entry)
65-
break;
66-
}
62+
} while (!try_cmpxchg(&head->first, &entry, next));
6763

6864
return entry;
6965
}

0 commit comments

Comments
 (0)