On Thu, Jul 10, 2025 at 03:15:28PM +0300, Andy Shevchenko wrote: > The list_for_each_rcu() relies on the rcu_dereference() API which is not > provided by the list.h. At the same time list.h is a low-level basic header > that must not have dependencies like RCU, besides the fact of the potential > circular dependencies in some cases. With all that said, move RCU related > API to the rculist.h where it belongs. > > Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
I cannot see why this would not work, and it does pass testing, but I am adding David Howells in case there is some subtle reason why this must remain in include/linux/list.h. ad25f5cb3987 ("rxrpc: Fix locking issue") In the absence of such a reason, from an RCU viewpoint: Reviewed-by: Paul E. McKenney <paul...@kernel.org> > --- > include/linux/list.h | 10 ---------- > include/linux/rculist.h | 10 ++++++++++ > kernel/cgroup/dmem.c | 1 + > 3 files changed, 11 insertions(+), 10 deletions(-) > > diff --git a/include/linux/list.h b/include/linux/list.h > index e7e28afd28f8..e7bdad9b8618 100644 > --- a/include/linux/list.h > +++ b/include/linux/list.h > @@ -686,16 +686,6 @@ static inline void list_splice_tail_init(struct > list_head *list, > #define list_for_each(pos, head) \ > for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) > > -/** > - * list_for_each_rcu - Iterate over a list in an RCU-safe fashion > - * @pos: the &struct list_head to use as a loop cursor. > - * @head: the head for your list. > - */ > -#define list_for_each_rcu(pos, head) \ > - for (pos = rcu_dereference((head)->next); \ > - !list_is_head(pos, (head)); \ > - pos = rcu_dereference(pos->next)) > - > /** > * list_for_each_continue - continue iteration over a list > * @pos: the &struct list_head to use as a loop cursor. > diff --git a/include/linux/rculist.h b/include/linux/rculist.h > index 1b11926ddd47..2abba7552605 100644 > --- a/include/linux/rculist.h > +++ b/include/linux/rculist.h > @@ -42,6 +42,16 @@ static inline void INIT_LIST_HEAD_RCU(struct list_head > *list) > */ > #define list_bidir_prev_rcu(list) (*((struct list_head __rcu > **)(&(list)->prev))) > > +/** > + * list_for_each_rcu - Iterate over a list in an RCU-safe fashion > + * @pos: the &struct list_head to use as a loop cursor. > + * @head: the head for your list. > + */ > +#define list_for_each_rcu(pos, head) \ > + for (pos = rcu_dereference((head)->next); \ > + !list_is_head(pos, (head)); \ > + pos = rcu_dereference(pos->next)) > + > /** > * list_tail_rcu - returns the prev pointer of the head of the list > * @head: the head of the list > diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c > index 10b63433f057..e12b946278b6 100644 > --- a/kernel/cgroup/dmem.c > +++ b/kernel/cgroup/dmem.c > @@ -14,6 +14,7 @@ > #include <linux/mutex.h> > #include <linux/page_counter.h> > #include <linux/parser.h> > +#include <linux/rculist.h> > #include <linux/slab.h> > > struct dmem_cgroup_region { > -- > 2.47.2 >