On 6/12/24 21:21, Keith Busch wrote: > From: Keith Busch <kbusch@xxxxxxxxxx> > > Provide a helper to remove elements from a list to the end, and place > those elements in a new list. > > Signed-off-by: Keith Busch <kbusch@xxxxxxxxxx> > --- > include/linux/list.h | 20 ++++++++++++++++++++ > lib/list-test.c | 29 +++++++++++++++++++++++++++++ > 2 files changed, 49 insertions(+) > > diff --git a/include/linux/list.h b/include/linux/list.h > index 5f4b0a39cf46a..f22850e854820 100644 > --- a/include/linux/list.h > +++ b/include/linux/list.h > @@ -520,6 +520,26 @@ static inline void list_cut_before(struct list_head *list, > entry->prev = head; > } > > +/** > + * list_cut - cut a list into two from the entry > + * @list: a new list to add all removed entries > + * @head: a list with entries > + * @entry: an entry within head, could be the head itself > + * > + * This helper removes elements from @head starting at @entry until the end, > + * and appends them to @lists. > + */ > +static inline void list_cut(struct list_head *list, > + struct list_head *head, struct list_head *entry) > +{ > + list->next = entry; > + list->prev = head->prev; > + head->prev = entry->prev; > + entry->prev->next = head; > + entry->prev = list; > + list->prev->next = list; > +} I am wondering whether we really need the _rcu version of list_cut here? I think that @head could point to an _rcu protected list and that's true for this patch. So there might be concurrent readers accessing @head using _rcu list-traversal primitives, such as list_for_each_entry_rcu(). An _rcu version of list_cut(): static inline void list_cut_rcu(struct list_head *list, struct list_head *head, struct list_head *entry) { list->next = entry; list->prev = head->prev; head->prev = entry->prev; rcu_assign_pointer(list_next_rcu(entry->prev), head); entry->prev = list; list->prev->next = list; } Thanks, --Nilay