From: Kaitao Cheng <kaitao.cheng@linux.dev>
To: "David Laight" <david.laight.linux@gmail.com>,
"Jani Nikula" <jani.nikula@linux.intel.com>,
"Christian König" <christian.koenig@amd.com>,
"David Hildenbrand" <david@kernel.org>,
"Nathan Chancellor" <nathan@kernel.org>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
"Nicolas Schier" <nsc@kernel.org>
Cc: Christian Brauner <brauner@kernel.org>,
"Paul E . McKenney" <paulmck@kernel.org>,
David Howells <dhowells@redhat.com>,
Simona Vetter <simona.vetter@ffwll.ch>,
Neeraj Upadhyay <neeraj.upadhyay@kernel.org>,
Luca Ceresoli <luca.ceresoli@bootlin.com>,
Randy Dunlap <rdunlap@infradead.org>,
Kaitao Cheng <chengkaitao@kylinos.cn>,
Andrew Morton <akpm@linux-foundation.org>,
Philipp Stanner <phasta@kernel.org>,
Alex Williamson <alex@shazbot.org>,
David Matlack <dmatlack@google.com>,
Shuah Khan <skhan@linuxfoundation.org>,
"Joy H . J . Lee" <rkr0k0r@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Ian Rogers <irogers@google.com>,
Namhyung Kim <namhyung@kernel.org>,
Swapnil Sapkal <swapnil.sapkal@amd.com>,
linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v4 4/4] scripts/list: Add mutable iterator variants
Date: Thu, 30 Jul 2026 17:50:36 +0800 [thread overview]
Message-ID: <20260730095041.35715-5-kaitao.cheng@linux.dev> (raw)
In-Reply-To: <20260730095041.35715-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
The kernel has added mutable iterator variants, so sync the scripts/list
implementation accordingly. The safe iterators require callers to declare
and pass a temporary cursor even when the loop body only needs to remove
the current entry.
Add list_for_each_entry_mutable() and hlist_for_each_entry_mutable() so
callers can use removal-safe iteration without exposing the temporary
cursor. Keep the existing safe variants for users that need direct access
to the cursor, and document the distinction.
Add local __PASTE() and __UNIQUE_ID() helpers to generate the internal
cursor name, matching the format used by include/linux/compiler.h.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
scripts/include/list.h | 56 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 54 insertions(+), 2 deletions(-)
diff --git a/scripts/include/list.h b/scripts/include/list.h
index 8bdcaadca709..ff1c84339344 100644
--- a/scripts/include/list.h
+++ b/scripts/include/list.h
@@ -9,6 +9,16 @@
/* Are two types/vars the same type (ignoring qualifiers)? */
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+#ifndef __PASTE
+/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
+#define ___PASTE(a, b) a##b
+#define __PASTE(a, b) ___PASTE(a, b)
+#endif
+
+#ifndef __UNIQUE_ID
+#define __UNIQUE_ID(name) __PASTE(__UNIQUE_ID_, __PASTE(name, __PASTE(_, __COUNTER__)))
+#endif
+
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
@@ -298,11 +308,15 @@ static inline int list_empty(const struct list_head *head)
pos = list_prev_entry(pos, member))
/**
- * list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry
+ * list_for_each_entry_safe - iterate over list of given type safe against
+ * removal of list entry with a caller-provided temporary cursor
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
+ *
+ * If the caller does not need to access the temporary cursor, use
+ * list_for_each_entry_mutable() instead.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
@@ -310,6 +324,22 @@ static inline int list_empty(const struct list_head *head)
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))
+#define __list_for_each_entry_mutable(pos, tmp, head, member) \
+ for (typeof(pos) tmp = list_next_entry(pos = \
+ list_first_entry(head, typeof(*pos), member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = tmp, tmp = list_next_entry(tmp, member))
+
+/**
+ * list_for_each_entry_mutable - iterate over a list safe against removal of
+ * list entry with an internal temporary cursor
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_head within the struct.
+ */
+#define list_for_each_entry_mutable(pos, head, member) \
+ __list_for_each_entry_mutable(pos, __UNIQUE_ID(next), head, member)
+
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
@@ -414,15 +444,37 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
/**
- * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * hlist_for_each_entry_safe - iterate over list of given type safe against
+ * removal of list entry with a caller-provided temporary cursor
* @pos: the type * to use as a loop cursor.
* @n: a &struct hlist_node to use as temporary storage
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
+ *
+ * If the caller does not need to access the temporary cursor, use
+ * hlist_for_each_entry_mutable() instead.
*/
#define hlist_for_each_entry_safe(pos, n, head, member) \
for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
pos && ({ n = pos->member.next; 1; }); \
pos = hlist_entry_safe(n, typeof(*pos), member))
+#define __hlist_for_each_entry_mutable(pos, tmp, head, member) \
+ for (struct hlist_node *tmp = (pos = \
+ hlist_entry_safe((head)->first, typeof(*pos), member)) ? \
+ pos->member.next : NULL; \
+ pos; \
+ pos = hlist_entry_safe(tmp, typeof(*pos), member), \
+ tmp = pos ? pos->member.next : NULL)
+
+/**
+ * hlist_for_each_entry_mutable - iterate over hlist safe against removal of
+ * list entry with an internal temporary cursor
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your hlist.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_mutable(pos, head, member) \
+ __hlist_for_each_entry_mutable(pos, __UNIQUE_ID(next), head, member)
+
#endif /* LIST_H */
--
2.43.0
prev parent reply other threads:[~2026-07-30 9:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-30 9:50 [PATCH v4 0/4] Prepare mutable list iterators to cache cursor state Kaitao Cheng
2026-07-30 9:50 ` [PATCH v4 1/4] list: Add mutable iterator variants Kaitao Cheng
2026-07-30 9:50 ` [PATCH v4 2/4] llist: " Kaitao Cheng
2026-07-30 9:50 ` [PATCH v4 3/4] tools/list: " Kaitao Cheng
2026-07-30 9:50 ` Kaitao Cheng [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260730095041.35715-5-kaitao.cheng@linux.dev \
--to=kaitao.cheng@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=alex@shazbot.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=brauner@kernel.org \
--cc=chengkaitao@kylinos.cn \
--cc=christian.koenig@amd.com \
--cc=david.laight.linux@gmail.com \
--cc=david@kernel.org \
--cc=dhowells@redhat.com \
--cc=dmatlack@google.com \
--cc=irogers@google.com \
--cc=jani.nikula@linux.intel.com \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luca.ceresoli@bootlin.com \
--cc=namhyung@kernel.org \
--cc=nathan@kernel.org \
--cc=neeraj.upadhyay@kernel.org \
--cc=nsc@kernel.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=phasta@kernel.org \
--cc=rdunlap@infradead.org \
--cc=rkr0k0r@gmail.com \
--cc=simona.vetter@ffwll.ch \
--cc=skhan@linuxfoundation.org \
--cc=swapnil.sapkal@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.