Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

llist: add llist_del_first_this()

llist_del_first_this() deletes a specific entry from an llist, providing
it is at the head of the list. Multiple threads can call this
concurrently providing they each offer a different entry.

This can be uses for a set of worker threads which are on the llist when
they are idle. The head can always be woken, and when it is woken it
can remove itself, and possibly wake the next if there is an excess of
work to do.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

NeilBrown and committed by
Chuck Lever
8a3e5975 9bd4161c

+32
+4
include/linux/llist.h
··· 291 291 init_llist_node(n); 292 292 return n; 293 293 } 294 + 295 + extern bool llist_del_first_this(struct llist_head *head, 296 + struct llist_node *this); 297 + 294 298 struct llist_node *llist_reverse_order(struct llist_node *head); 295 299 296 300 #endif /* LLIST_H */
+28
lib/llist.c
··· 66 66 EXPORT_SYMBOL_GPL(llist_del_first); 67 67 68 68 /** 69 + * llist_del_first_this - delete given entry of lock-less list if it is first 70 + * @head: the head for your lock-less list 71 + * @this: a list entry. 72 + * 73 + * If head of the list is given entry, delete and return %true else 74 + * return %false. 75 + * 76 + * Multiple callers can safely call this concurrently with multiple 77 + * llist_add() callers, providing all the callers offer a different @this. 78 + */ 79 + bool llist_del_first_this(struct llist_head *head, 80 + struct llist_node *this) 81 + { 82 + struct llist_node *entry, *next; 83 + 84 + /* acquire ensures orderig wrt try_cmpxchg() is llist_del_first() */ 85 + entry = smp_load_acquire(&head->first); 86 + do { 87 + if (entry != this) 88 + return false; 89 + next = READ_ONCE(entry->next); 90 + } while (!try_cmpxchg(&head->first, &entry, next)); 91 + 92 + return true; 93 + } 94 + EXPORT_SYMBOL_GPL(llist_del_first_this); 95 + 96 + /** 69 97 * llist_reverse_order - reverse order of a llist chain 70 98 * @head: first item of the list to be reversed 71 99 *