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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox