* [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
@ 2026-06-09 6:13 Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 01/14] drbd: Open-code transfer log list walk Kaitao Cheng
` (6 more replies)
0 siblings, 7 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:13 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaito Cheng
From: Kaito Cheng <chengkaitao@kylinos.cn>
This series prepares for, and then updates, the list_for_each_entry()
family so the common entry iterators cache their next or previous cursor
before the loop body runs.
The first 13 patches open-code loops that intentionally depend on the
old "derive the next entry from the current cursor at the end of the
iteration" behaviour. These loops append work to the list being walked,
restart traversal after dropping a lock, skip an entry consumed by the
current iteration, or otherwise adjust the cursor in the loop body.
The final patch changes include/linux/list.h to keep a private cursor in
the common entry iterators while preserving the public macro interface.
The safe variants remain available when callers need the temporary
cursor explicitly or have stronger mutation requirements.
Changes in v2 (Muchun Song, Andy Shevchenko):
- Drop the list_for_each_entry_mutable*() helpers from v1 and make the
cursor change directly in the existing list_for_each_entry*() helpers.
- Open-code special list walks that rely on updating the loop cursor in
the body, preserving their existing traversal semantics.
Link to v1:
https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@linux.dev/
Kaitao Cheng (14):
drbd: Open-code transfer log list walk
firewire: core: Open-code topology list walk
drm/bridge: Open-code bridge chain list walks
drm/i915/gt: Open-code active timeline walk
drm/i915: Open-code DFS dependency list walk
drm/ttm: Open-code reservation list walk
spi: fsi: Open-code message transfer walk
spi: stm32-ospi: Open-code message transfer walk
spi: stm32-qspi: Open-code message transfer walk
spi: tegra210-quad: Open-code message transfer walk
locking/locktorture: Open-code ww mutex list walk
locking/ww_mutex: Open-code stress reorder list walk
ASoC: dapm: Open-code widget invalidation walk
list: Cache cursors in entry iterators
drivers/block/drbd/drbd_debugfs.c | 4 ++-
drivers/firewire/core-topology.c | 4 ++-
drivers/gpu/drm/drm_bridge.c | 7 ++--
drivers/gpu/drm/i915/gt/intel_reset.c | 4 ++-
drivers/gpu/drm/i915/i915_scheduler.c | 4 ++-
drivers/gpu/drm/ttm/ttm_execbuf_util.c | 4 ++-
drivers/spi/spi-fsi.c | 5 ++-
drivers/spi/spi-stm32-ospi.c | 4 ++-
drivers/spi/spi-stm32-qspi.c | 5 ++-
drivers/spi/spi-tegra210-quad.c | 4 ++-
include/linux/list.h | 46 ++++++++++++++++++++------
kernel/locking/locktorture.c | 4 ++-
kernel/locking/test-ww_mutex.c | 4 ++-
sound/soc/soc-dapm.c | 4 ++-
14 files changed, 78 insertions(+), 25 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 01/14] drbd: Open-code transfer log list walk
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
@ 2026-06-09 6:13 ` Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 02/14] firewire: core: Open-code topology " Kaitao Cheng
` (5 subsequent siblings)
6 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:13 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. That is the desired behaviour for the
common case, but this transfer log walk temporarily drops
resource->req_lock and revalidates the cursor before continuing.
Keep the loop open-coded so the next request is derived after the body
has completed and after the cursor has been adjusted. This preserves the
existing traversal semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/block/drbd/drbd_debugfs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/block/drbd/drbd_debugfs.c b/drivers/block/drbd/drbd_debugfs.c
index 12460b584bcb..e90cead90e9d 100644
--- a/drivers/block/drbd/drbd_debugfs.c
+++ b/drivers/block/drbd/drbd_debugfs.c
@@ -308,7 +308,9 @@ static void seq_print_resource_transfer_log_summary(struct seq_file *m,
seq_puts(m, "n\tdevice\tvnr\t" RQ_HDR);
spin_lock_irq(&resource->req_lock);
- list_for_each_entry(req, &connection->transfer_log, tl_requests) {
+ for (req = list_first_entry(&connection->transfer_log, typeof(*req), tl_requests);
+ !list_entry_is_head(req, &connection->transfer_log, tl_requests);
+ req = list_next_entry(req, tl_requests)) {
unsigned int tmp = 0;
unsigned int s;
++count;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 02/14] firewire: core: Open-code topology list walk
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 01/14] drbd: Open-code transfer log list walk Kaitao Cheng
@ 2026-06-09 6:13 ` Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
` (4 subsequent siblings)
6 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:13 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. for_each_fw_node() intentionally appends
newly discovered child nodes to the temporary walk list while the list is
being traversed.
Keep the loop open-coded so the next node is looked up only after
children have been appended. This preserves the current breadth-first
traversal semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/firewire/core-topology.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c
index bb2d2db30795..df2ac0dab106 100644
--- a/drivers/firewire/core-topology.c
+++ b/drivers/firewire/core-topology.c
@@ -272,7 +272,9 @@ static void for_each_fw_node(struct fw_card *card, struct fw_node *root,
fw_node_get(root);
list_add_tail(&root->link, &list);
parent = NULL;
- list_for_each_entry(node, &list, link) {
+ for (node = list_first_entry(&list, typeof(*node), link);
+ !list_entry_is_head(node, &list, link);
+ node = list_next_entry(node, link)) {
node->color = card->color;
for (i = 0; i < node->port_count; i++) {
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 01/14] drbd: Open-code transfer log list walk Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 02/14] firewire: core: Open-code topology " Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
` (5 more replies)
2026-06-09 6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
` (3 subsequent siblings)
6 siblings, 6 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry_from() and
list_for_each_entry_reverse() cache the next or previous element before
entering the loop body. The bridge enable and disable ordering code
adjusts its cursor to skip ranges that have already been handled.
Keep those walks open-coded so the loop step observes the cursor
selected by the body. This preserves the existing bridge ordering
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/drm_bridge.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index d6f512b73389..a538aabc4e0b 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -868,7 +868,8 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
encoder = bridge->encoder;
- list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ for (; !list_entry_is_head(bridge, &encoder->bridge_chain, chain_node);
+ bridge = list_next_entry(bridge, chain_node)) {
limit = NULL;
if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) {
@@ -962,7 +963,9 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
encoder = bridge->encoder;
- list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ for (iter = list_last_entry(&encoder->bridge_chain, typeof(*iter), chain_node);
+ !list_entry_is_head(iter, &encoder->bridge_chain, chain_node);
+ iter = list_prev_entry(iter, chain_node)) {
if (iter->pre_enable_prev_first) {
next = iter;
limit = bridge;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
2026-06-09 7:00 ` Andy Shevchenko
2026-06-09 6:25 ` [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk Kaitao Cheng
` (4 subsequent siblings)
5 siblings, 1 reply; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. __intel_gt_unset_wedged() drops
timelines->lock while waiting on a fence and then restarts the walk from
the list head after the lock is reacquired.
Keep the loop open-coded so the next timeline is selected after that
restart logic has run. This preserves the existing lock-drop traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/i915/gt/intel_reset.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index adff482a6c9c..fe0d87e248a7 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1077,7 +1077,9 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
* No more can be submitted until we reset the wedged bit.
*/
spin_lock(&timelines->lock);
- list_for_each_entry(tl, &timelines->active_list, link) {
+ for (tl = list_first_entry(&timelines->active_list, typeof(*tl), link);
+ !list_entry_is_head(tl, &timelines->active_list, link);
+ tl = list_next_entry(tl, link)) {
struct dma_fence *fence;
fence = i915_active_fence_get(&tl->last_request);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 06/14] drm/ttm: Open-code reservation " Kaitao Cheng
` (3 subsequent siblings)
5 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. __i915_schedule() builds its DFS work list
while walking it by moving newly discovered dependencies to the tail.
Keep the DFS walk open-coded so the next dependency is resolved after any
tail moves performed by the body. This preserves the existing traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/i915/i915_scheduler.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index aec1342402ca..da1f60282df8 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -190,7 +190,9 @@ static void __i915_schedule(struct i915_sched_node *node,
* end result is a topological list of requests in reverse order, the
* last element in the list is the request we must execute first.
*/
- list_for_each_entry(dep, &dfs, dfs_link) {
+ for (dep = list_first_entry(&dfs, typeof(*dep), dfs_link);
+ !list_entry_is_head(dep, &dfs, dfs_link);
+ dep = list_next_entry(dep, dfs_link)) {
struct i915_sched_node *node = dep->signaler;
/* If we are already flying, we know we have no signalers */
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 06/14] drm/ttm: Open-code reservation list walk
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 07/14] spi: fsi: Open-code message transfer walk Kaitao Cheng
` (2 subsequent siblings)
5 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. ttm_eu_reserve_buffers() may move the
current validation buffer to the duplicates list and then rewinds the
cursor before continuing.
Keep the reservation walk open-coded so the loop step uses the cursor
selected by that duplicate handling. This preserves the existing
traversal semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/ttm/ttm_execbuf_util.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index bc7a83a9fe44..8072f07d5557 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -86,7 +86,9 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
if (ticket)
ww_acquire_init(ticket, &reservation_ww_class);
- list_for_each_entry(entry, list, head) {
+ for (entry = list_first_entry(list, typeof(*entry), head);
+ !list_entry_is_head(entry, list, head);
+ entry = list_next_entry(entry, head)) {
struct ttm_buffer_object *bo = entry->bo;
unsigned int num_fences;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 07/14] spi: fsi: Open-code message transfer walk
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
` (2 preceding siblings ...)
2026-06-09 6:25 ` [PATCH v2 06/14] drm/ttm: Open-code reservation " Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
2026-06-09 7:02 ` Andy Shevchenko
2026-06-09 6:25 ` [PATCH v2 08/14] spi: stm32-ospi: " Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 09/14] spi: stm32-qspi: " Kaitao Cheng
5 siblings, 1 reply; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. fsi_spi_transfer_one_message() can combine
the current transfer with the following transfer and then advance the
cursor to that consumed entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-fsi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c
index f6a75f0184c4..44999f00f5f6 100644
--- a/drivers/spi/spi-fsi.c
+++ b/drivers/spi/spi-fsi.c
@@ -434,7 +434,10 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
if (rc)
goto error;
- list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&mesg->transfers,
+ typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &mesg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
struct fsi_spi_sequence seq;
struct spi_transfer *next = NULL;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 08/14] spi: stm32-ospi: Open-code message transfer walk
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
` (3 preceding siblings ...)
2026-06-09 6:25 ` [PATCH v2 07/14] spi: fsi: Open-code message transfer walk Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 09/14] spi: stm32-qspi: " Kaitao Cheng
5 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. stm32_ospi_transfer_one_message() can
consume the following transfer as part of the current operation and then
advance the loop cursor to that entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-stm32-ospi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c
index 4461c6e24b9e..4dc2b56b4c20 100644
--- a/drivers/spi/spi-stm32-ospi.c
+++ b/drivers/spi/spi-stm32-ospi.c
@@ -675,7 +675,9 @@ static int stm32_ospi_transfer_one_message(struct spi_controller *ctrl,
gpiod_set_value_cansleep(cs_gpiod, true);
- list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&msg->transfers, typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &msg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
u8 dummy_bytes = 0;
memset(&op, 0, sizeof(op));
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 09/14] spi: stm32-qspi: Open-code message transfer walk
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
` (4 preceding siblings ...)
2026-06-09 6:25 ` [PATCH v2 08/14] spi: stm32-ospi: " Kaitao Cheng
@ 2026-06-09 6:25 ` Kaitao Cheng
5 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. stm32_qspi_transfer_one_message() can
consume the following transfer as part of the current operation and then
advance the loop cursor to that entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-stm32-qspi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index df1bbacec90a..27d82a578c9f 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -577,7 +577,10 @@ static int stm32_qspi_transfer_one_message(struct spi_controller *ctrl,
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), true);
- list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&msg->transfers,
+ typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &msg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
u8 dummy_bytes = 0;
memset(&op, 0, sizeof(op));
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 10/14] spi: tegra210-quad: Open-code message transfer walk
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
` (2 preceding siblings ...)
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
@ 2026-06-09 6:38 ` Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder " Kaitao Cheng
2026-06-09 6:41 ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk Kaitao Cheng
` (2 subsequent siblings)
6 siblings, 2 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:38 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. tegra_qspi_non_combined_seq_xfer() can
consume the following transfer as part of the current operation and then
advance the loop cursor to that entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-tegra210-quad.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index db28dd556484..42dd5cf53c67 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -1302,7 +1302,9 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
if (tqspi->soc_data->supports_tpm)
val &= ~QSPI_TPM_WAIT_POLL_EN;
tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG);
- list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&msg->transfers, typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &msg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
struct spi_transfer *xfer = transfer;
u8 dummy_bytes = 0;
u32 cmd1;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk
2026-06-09 6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
@ 2026-06-09 6:38 ` Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder " Kaitao Cheng
1 sibling, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:38 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. The ww-mutex torture path can move list
entries while it resolves a wound/wait conflict and then continue from
the adjusted cursor.
Keep the list walk open-coded so the loop step observes the cursor
selected by the body. This preserves the existing stress-test traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
kernel/locking/locktorture.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index e618bcf75e2d..0eb75e9bccaa 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -644,7 +644,9 @@ __acquires(torture_ww_mutex_2)
ww_acquire_init(ctx, &torture_ww_class);
- list_for_each_entry(ll, &list, link) {
+ for (ll = list_first_entry(&list, typeof(*ll), link);
+ !list_entry_is_head(ll, &list, link);
+ ll = list_next_entry(ll, link)) {
int err;
err = ww_mutex_lock(ll->lock, ctx);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder list walk
2026-06-09 6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk Kaitao Cheng
@ 2026-06-09 6:38 ` Kaitao Cheng
1 sibling, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:38 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. stress_reorder_work() can move list
entries while handling wound/wait locking conflicts and then continue
from the adjusted cursor.
Keep the list walk open-coded so the loop step observes the cursor
selected by the body. This preserves the existing stress-test traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
kernel/locking/test-ww_mutex.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c
index 838d631544ed..08a6ab5ac041 100644
--- a/kernel/locking/test-ww_mutex.c
+++ b/kernel/locking/test-ww_mutex.c
@@ -519,7 +519,9 @@ static void stress_reorder_work(struct work_struct *work)
do {
ww_acquire_init(&ctx, stress->class);
- list_for_each_entry(ll, &locks, link) {
+ for (ll = list_first_entry(&locks, typeof(*ll), link);
+ !list_entry_is_head(ll, &locks, link);
+ ll = list_next_entry(ll, link)) {
err = ww_mutex_lock(ll->lock, &ctx);
if (!err)
continue;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
` (3 preceding siblings ...)
2026-06-09 6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
@ 2026-06-09 6:41 ` Kaitao Cheng
2026-06-09 6:41 ` [PATCH v2 14/14] list: Cache cursors in entry iterators Kaitao Cheng
2026-06-09 6:47 ` [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Andy Shevchenko
2026-06-09 10:33 ` Christian König
6 siblings, 1 reply; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:41 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. dapm_widget_invalidate_paths() appends
newly reached widgets to the temporary work list while walking it.
Keep the work-list walk open-coded so the next widget is looked up after
new widgets have been appended. This preserves the existing invalidation
traversal semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
sound/soc/soc-dapm.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d6192204e613..5bd921fca132 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -255,7 +255,9 @@ static __always_inline void dapm_widget_invalidate_paths(
list_add_tail(&w->work_list, &list);
w->endpoints[dir] = -1;
- list_for_each_entry(w, &list, work_list) {
+ for (w = list_first_entry(&list, typeof(*w), work_list);
+ !list_entry_is_head(w, &list, work_list);
+ w = list_next_entry(w, work_list)) {
snd_soc_dapm_widget_for_each_path(w, dir, p) {
if (p->is_supply || !p->connect)
continue;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v2 14/14] list: Cache cursors in entry iterators
2026-06-09 6:41 ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk Kaitao Cheng
@ 2026-06-09 6:41 ` Kaitao Cheng
0 siblings, 0 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-09 6:41 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
From: Kaitao Cheng <chengkaitao@kylinos.cn>
The non-safe list_for_each_entry() family advances by deriving the next
element from the current cursor in the loop step. If the loop body
unlinks the current entry, the step can no longer rely on the current
entry's list pointers.
Callers can use the _safe variants today, but those interfaces require a
temporary cursor to be declared outside the macro. That is necessary when
the caller actually needs the temporary cursor, but it looks redundant
and awkward when the cursor is only there to satisfy the macro and is
never otherwise used.
Add private next and previous cursors for the common entry iterators and
use unique internal names so callers keep the same interface. This lets
the loop step use a cursor captured before the body runs, while callers
that need to alter traversal state can still open-code the walk.
The safe variants remain useful when the caller needs access to the
temporary cursor or has stronger mutation requirements. Update their
comments to steer users toward the simpler iterators when that temporary
cursor is not needed.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
include/linux/list.h | 46 +++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/include/linux/list.h b/include/linux/list.h
index 09d979976b3b..9df84a56a789 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -809,6 +809,29 @@ static inline size_t list_count_nodes(struct list_head *head)
#define list_entry_is_head(pos, head, member) \
list_is_head(&pos->member, (head))
+#define __list_for_each_entry(pos, next, head, member) \
+ for (typeof(pos) next = list_next_entry(pos = \
+ list_first_entry(head, typeof(*pos), member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = next, next = list_next_entry(next, member))
+
+#define __list_for_each_entry_reverse(pos, prev, head, member) \
+ for (typeof(pos) prev = list_prev_entry(pos = \
+ list_last_entry(head, typeof(*pos), member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = prev, prev = list_prev_entry(prev, member))
+
+#define __list_for_each_entry_continue(pos, next, head, member) \
+ for (typeof(pos) next = list_next_entry(pos = \
+ list_next_entry(pos, member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = next, next = list_next_entry(next, member))
+
+#define __list_for_each_entry_from(pos, next, head, member) \
+ for (typeof(pos) next = list_next_entry(pos, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = next, next = list_next_entry(next, member))
+
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
@@ -816,9 +839,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
- for (pos = list_first_entry(head, typeof(*pos), member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+ __list_for_each_entry(pos, __UNIQUE_ID(next), head, member)
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
@@ -827,9 +848,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_last_entry(head, typeof(*pos), member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_prev_entry(pos, member))
+ __list_for_each_entry_reverse(pos, __UNIQUE_ID(prev), head, member)
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
@@ -852,9 +871,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* the current position.
*/
#define list_for_each_entry_continue(pos, head, member) \
- for (pos = list_next_entry(pos, member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+ __list_for_each_entry_continue(pos, __UNIQUE_ID(next), head, member)
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
@@ -879,8 +896,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* Iterate over list of given type, continuing from current position.
*/
#define list_for_each_entry_from(pos, head, member) \
- for (; !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+ __list_for_each_entry_from(pos, __UNIQUE_ID(next), head, member)
/**
* list_for_each_entry_from_reverse - iterate backwards over list of given type
@@ -901,6 +917,8 @@ static inline size_t list_count_nodes(struct list_head *head)
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
+ *
+ * Prefer list_for_each_entry() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
@@ -917,6 +935,8 @@ static inline size_t list_count_nodes(struct list_head *head)
*
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
+ *
+ * Prefer list_for_each_entry_continue() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_next_entry(pos, member), \
@@ -933,6 +953,8 @@ static inline size_t list_count_nodes(struct list_head *head)
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
+ *
+ * Prefer list_for_each_entry_from() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_next_entry(pos, member); \
@@ -948,6 +970,8 @@ static inline size_t list_count_nodes(struct list_head *head)
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
+ *
+ * Prefer list_for_each_entry_reverse() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_last_entry(head, typeof(*pos), member), \
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
` (4 preceding siblings ...)
2026-06-09 6:41 ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk Kaitao Cheng
@ 2026-06-09 6:47 ` Andy Shevchenko
2026-06-09 7:05 ` Andy Shevchenko
2026-06-09 10:33 ` Christian König
6 siblings, 1 reply; 26+ messages in thread
From: Andy Shevchenko @ 2026-06-09 6:47 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaito Cheng
On Tue, Jun 09, 2026 at 02:13:33PM +0800, Kaitao Cheng wrote:
>
> This series prepares for, and then updates, the list_for_each_entry()
> family so the common entry iterators cache their next or previous cursor
> before the loop body runs.
>
> The first 13 patches open-code loops that intentionally depend on the
> old "derive the next entry from the current cursor at the end of the
> iteration" behaviour. These loops append work to the list being walked,
> restart traversal after dropping a lock, skip an entry consumed by the
> current iteration, or otherwise adjust the cursor in the loop body.
>
> The final patch changes include/linux/list.h to keep a private cursor in
> the common entry iterators while preserving the public macro interface.
> The safe variants remain available when callers need the temporary
> cursor explicitly or have stronger mutation requirements.
Something is really wrong with the patch series email chaining.
Patches 3, 10, and 13 start the subthreads. Please, check your
tools and fix them accordingly.
Note, `git format-patch ...` should not have this "side-effect"
when used correctly.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk
2026-06-09 6:25 ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
@ 2026-06-09 7:00 ` Andy Shevchenko
0 siblings, 0 replies; 26+ messages in thread
From: Andy Shevchenko @ 2026-06-09 7:00 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaitao Cheng
On Tue, Jun 09, 2026 at 02:25:16PM +0800, Kaitao Cheng wrote:
>
> A later change will make list_for_each_entry() cache the next element
> before entering the loop body. __intel_gt_unset_wedged() drops
> timelines->lock while waiting on a fence and then restarts the walk from
> the list head after the lock is reacquired.
>
> Keep the loop open-coded so the next timeline is selected after that
> restart logic has run. This preserves the existing lock-drop traversal
> semantics and prepares the code for the list iterator update.
...
> spin_lock(&timelines->lock);
> - list_for_each_entry(tl, &timelines->active_list, link) {
> + for (tl = list_first_entry(&timelines->active_list, typeof(*tl), link);
> + !list_entry_is_head(tl, &timelines->active_list, link);
> + tl = list_next_entry(tl, link)) {
Yeah, these cases should rather be converted to do {} while or while-loop.
This will make the intention clearer and reduces the possibility that someone
mistakenly changes these back to use list_for_each_entry().
See, for example, deferred_probe_work_func() implementation.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 07/14] spi: fsi: Open-code message transfer walk
2026-06-09 6:25 ` [PATCH v2 07/14] spi: fsi: Open-code message transfer walk Kaitao Cheng
@ 2026-06-09 7:02 ` Andy Shevchenko
0 siblings, 0 replies; 26+ messages in thread
From: Andy Shevchenko @ 2026-06-09 7:02 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaitao Cheng
On Tue, Jun 09, 2026 at 02:25:19PM +0800, Kaitao Cheng wrote:
>
> A later change will make list_for_each_entry() cache the next element
> before entering the loop body. fsi_spi_transfer_one_message() can combine
> the current transfer with the following transfer and then advance the
> cursor to that consumed entry.
>
> Keep the transfer walk open-coded so the loop step observes that cursor
> update and skips the consumed transfer. This preserves the existing
> message sequencing semantics and prepares the code for the list iterator
> update.
...
> - list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
> + for (transfer = list_first_entry(&mesg->transfers,
> + typeof(*transfer), transfer_list);
You can keep this on a single line for more logical split.
for (transfer = list_first_entry(&mesg->transfers, typeof(*transfer), transfer_list);
it's under relaxed limits for the line length.
> + !list_entry_is_head(transfer, &mesg->transfers, transfer_list);
> + transfer = list_next_entry(transfer, transfer_list)) {
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-09 6:47 ` [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Andy Shevchenko
@ 2026-06-09 7:05 ` Andy Shevchenko
0 siblings, 0 replies; 26+ messages in thread
From: Andy Shevchenko @ 2026-06-09 7:05 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaito Cheng
On Tue, Jun 09, 2026 at 09:47:34AM +0300, Andy Shevchenko wrote:
> On Tue, Jun 09, 2026 at 02:13:33PM +0800, Kaitao Cheng wrote:
> >
> > This series prepares for, and then updates, the list_for_each_entry()
> > family so the common entry iterators cache their next or previous cursor
> > before the loop body runs.
While code looks okay, this doesn't explain "why?" aspects.
> > The first 13 patches open-code loops that intentionally depend on the
> > old "derive the next entry from the current cursor at the end of the
> > iteration" behaviour. These loops append work to the list being walked,
> > restart traversal after dropping a lock, skip an entry consumed by the
> > current iteration, or otherwise adjust the cursor in the loop body.
> >
> > The final patch changes include/linux/list.h to keep a private cursor in
> > the common entry iterators while preserving the public macro interface.
> > The safe variants remain available when callers need the temporary
> > cursor explicitly or have stronger mutation requirements.
>
> Something is really wrong with the patch series email chaining.
> Patches 3, 10, and 13 start the subthreads. Please, check your
> tools and fix them accordingly.
>
> Note, `git format-patch ...` should not have this "side-effect"
> when used correctly.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
` (5 preceding siblings ...)
2026-06-09 6:47 ` [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Andy Shevchenko
@ 2026-06-09 10:33 ` Christian König
2026-06-10 6:14 ` Kaitao Cheng
6 siblings, 1 reply; 26+ messages in thread
From: Christian König @ 2026-06-09 10:33 UTC (permalink / raw)
To: Kaitao Cheng, Andy Shevchenko, Muchun Song, Philipp Reisner,
Lars Ellenberg, Christoph Böhmwalder, Jens Axboe,
Takashi Sakamoto, Andrzej Hajda, Neil Armstrong, Robert Foss,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Tvrtko Ursulin, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaito Cheng
On 6/9/26 08:13, Kaitao Cheng wrote:
> From: Kaito Cheng <chengkaitao@kylinos.cn>
>
> This series prepares for, and then updates, the list_for_each_entry()
> family so the common entry iterators cache their next or previous cursor
> before the loop body runs.
Why in the world would we want to do that?
The safe and non-safe variants have very distinct use cases and that is completely intentional.
What we could improve maybe is the documentation, from my experience an astonishing large amount of people have misconceptions about the safe variants.
> The first 13 patches open-code loops that intentionally depend on the
> old "derive the next entry from the current cursor at the end of the
> iteration" behaviour. These loops append work to the list being walked,
> restart traversal after dropping a lock, skip an entry consumed by the
> current iteration, or otherwise adjust the cursor in the loop body.
Well I have to clearly reject the changes for subsystems/components I'm maintaining, that just looks horrible to me and I clearly don't see a good reason for that.
Regards,
Christian.
>
> The final patch changes include/linux/list.h to keep a private cursor in
> the common entry iterators while preserving the public macro interface.
> The safe variants remain available when callers need the temporary
> cursor explicitly or have stronger mutation requirements.
>
> Changes in v2 (Muchun Song, Andy Shevchenko):
> - Drop the list_for_each_entry_mutable*() helpers from v1 and make the
> cursor change directly in the existing list_for_each_entry*() helpers.
> - Open-code special list walks that rely on updating the loop cursor in
> the body, preserving their existing traversal semantics.
>
> Link to v1:
> https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@linux.dev/
>
> Kaitao Cheng (14):
> drbd: Open-code transfer log list walk
> firewire: core: Open-code topology list walk
> drm/bridge: Open-code bridge chain list walks
> drm/i915/gt: Open-code active timeline walk
> drm/i915: Open-code DFS dependency list walk
> drm/ttm: Open-code reservation list walk
> spi: fsi: Open-code message transfer walk
> spi: stm32-ospi: Open-code message transfer walk
> spi: stm32-qspi: Open-code message transfer walk
> spi: tegra210-quad: Open-code message transfer walk
> locking/locktorture: Open-code ww mutex list walk
> locking/ww_mutex: Open-code stress reorder list walk
> ASoC: dapm: Open-code widget invalidation walk
> list: Cache cursors in entry iterators
>
> drivers/block/drbd/drbd_debugfs.c | 4 ++-
> drivers/firewire/core-topology.c | 4 ++-
> drivers/gpu/drm/drm_bridge.c | 7 ++--
> drivers/gpu/drm/i915/gt/intel_reset.c | 4 ++-
> drivers/gpu/drm/i915/i915_scheduler.c | 4 ++-
> drivers/gpu/drm/ttm/ttm_execbuf_util.c | 4 ++-
> drivers/spi/spi-fsi.c | 5 ++-
> drivers/spi/spi-stm32-ospi.c | 4 ++-
> drivers/spi/spi-stm32-qspi.c | 5 ++-
> drivers/spi/spi-tegra210-quad.c | 4 ++-
> include/linux/list.h | 46 ++++++++++++++++++++------
> kernel/locking/locktorture.c | 4 ++-
> kernel/locking/test-ww_mutex.c | 4 ++-
> sound/soc/soc-dapm.c | 4 ++-
> 14 files changed, 78 insertions(+), 25 deletions(-)
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-09 10:33 ` Christian König
@ 2026-06-10 6:14 ` Kaitao Cheng
2026-06-10 8:07 ` Christian König
2026-06-10 14:43 ` Andy Shevchenko
0 siblings, 2 replies; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-10 6:14 UTC (permalink / raw)
To: Christian König, Andy Shevchenko
Cc: Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Huang Rui,
Eddie James, Mark Brown, Maxime Coquelin, Alexandre Torgue,
Laxman Dewangan, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaito Cheng, Muchun Song, Philipp Reisner,
Lars Ellenberg, Christoph Böhmwalder, Jens Axboe,
Takashi Sakamoto, Andrzej Hajda, Jaroslav Kysela, Takashi Iwai
在 2026/6/9 18:33, Christian König 写道:
> On 6/9/26 08:13, Kaitao Cheng wrote:
>> From: Kaito Cheng <chengkaitao@kylinos.cn>
>>
>> This series prepares for, and then updates, the list_for_each_entry()
>> family so the common entry iterators cache their next or previous cursor
>> before the loop body runs.
>
> Why in the world would we want to do that?
>
> The safe and non-safe variants have very distinct use cases and that is completely intentional.
>
> What we could improve maybe is the documentation, from my experience an astonishing large amount of people have misconceptions about the safe variants.
>
>> The first 13 patches open-code loops that intentionally depend on the
>> old "derive the next entry from the current cursor at the end of the
>> iteration" behaviour. These loops append work to the list being walked,
>> restart traversal after dropping a lock, skip an entry consumed by the
>> current iteration, or otherwise adjust the cursor in the loop body.
>
> Well I have to clearly reject the changes for subsystems/components I'm maintaining, that just looks horrible to me and I clearly don't see a good reason for that.
Hi Christian and Andy Shevchenko,
Thanks for taking a look. I would like to clarify the point you raised.
The reason I started looking at this is the original motivation behind
the _safe() variants. They exist because some users need to remove, move
or otherwise consume the current entry while walking the list. In that
case the next cursor has to be preserved before the loop body can modify
the current entry.
The unfortunate part is that this could not be expressed with the
existing list_for_each_entry() interface without changing its calling
convention. The _safe() variants had to grow an extra argument for the
temporary cursor, and that is why we ended up with a separate family of
macros.
But conceptually, the distinction does not have to be exposed as two
different iterator families forever. The difference is an implementation
detail: whether the iterator keeps the next/previous cursor before the
body runs. This series makes the common list_for_each_entry() iterators
do that internally, so the safe and non-safe forms can effectively be
folded together, or at least the need for a separate public _safe()
interface becomes much weaker.
There is also a usability issue with the current _safe() interface. The
caller is forced to define a temporary cursor outside the macro and pass
it in, even though almost all users never use that cursor directly. It is
just boilerplate required by the macro implementation. I find that
redundant and awkward: the temporary cursor is an internal detail of the
iteration, but every caller has to spell it out.
With the updated list_for_each_entry() implementation, that extra cursor
can be kept inside the iterator itself. Callers that only want to walk
the list, including callers that delete or consume the current entry, no
longer need to carry an otherwise-unused temporary variable just to make
the macro work.
>>
>> The final patch changes include/linux/list.h to keep a private cursor in
>> the common entry iterators while preserving the public macro interface.
>> The safe variants remain available when callers need the temporary
>> cursor explicitly or have stronger mutation requirements.
>>
>> Changes in v2 (Muchun Song, Andy Shevchenko):
>> - Drop the list_for_each_entry_mutable*() helpers from v1 and make the
>> cursor change directly in the existing list_for_each_entry*() helpers.
>> - Open-code special list walks that rely on updating the loop cursor in
>> the body, preserving their existing traversal semantics.
>>
>> Link to v1:
>> https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@linux.dev/
>>
>> Kaitao Cheng (14):
>> drbd: Open-code transfer log list walk
>> firewire: core: Open-code topology list walk
>> drm/bridge: Open-code bridge chain list walks
>> drm/i915/gt: Open-code active timeline walk
>> drm/i915: Open-code DFS dependency list walk
>> drm/ttm: Open-code reservation list walk
>> spi: fsi: Open-code message transfer walk
>> spi: stm32-ospi: Open-code message transfer walk
>> spi: stm32-qspi: Open-code message transfer walk
>> spi: tegra210-quad: Open-code message transfer walk
>> locking/locktorture: Open-code ww mutex list walk
>> locking/ww_mutex: Open-code stress reorder list walk
>> ASoC: dapm: Open-code widget invalidation walk
>> list: Cache cursors in entry iterators
>>
>> drivers/block/drbd/drbd_debugfs.c | 4 ++-
>> drivers/firewire/core-topology.c | 4 ++-
>> drivers/gpu/drm/drm_bridge.c | 7 ++--
>> drivers/gpu/drm/i915/gt/intel_reset.c | 4 ++-
>> drivers/gpu/drm/i915/i915_scheduler.c | 4 ++-
>> drivers/gpu/drm/ttm/ttm_execbuf_util.c | 4 ++-
>> drivers/spi/spi-fsi.c | 5 ++-
>> drivers/spi/spi-stm32-ospi.c | 4 ++-
>> drivers/spi/spi-stm32-qspi.c | 5 ++-
>> drivers/spi/spi-tegra210-quad.c | 4 ++-
>> include/linux/list.h | 46 ++++++++++++++++++++------
>> kernel/locking/locktorture.c | 4 ++-
>> kernel/locking/test-ww_mutex.c | 4 ++-
>> sound/soc/soc-dapm.c | 4 ++-
>> 14 files changed, 78 insertions(+), 25 deletions(-)
>>
>> --
>> 2.43.0
>>
>
--
Thanks
Kaitao Cheng
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-10 6:14 ` Kaitao Cheng
@ 2026-06-10 8:07 ` Christian König
2026-06-10 8:18 ` Kaitao Cheng
2026-06-10 14:43 ` Andy Shevchenko
1 sibling, 1 reply; 26+ messages in thread
From: Christian König @ 2026-06-10 8:07 UTC (permalink / raw)
To: Kaitao Cheng, Andy Shevchenko
Cc: Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Huang Rui,
Eddie James, Mark Brown, Maxime Coquelin, Alexandre Torgue,
Laxman Dewangan, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaito Cheng, Muchun Song, Philipp Reisner,
Lars Ellenberg, Christoph Böhmwalder, Jens Axboe,
Takashi Sakamoto, Andrzej Hajda, Jaroslav Kysela, Takashi Iwai
On 6/10/26 08:14, Kaitao Cheng wrote:
> 在 2026/6/9 18:33, Christian König 写道:
>> On 6/9/26 08:13, Kaitao Cheng wrote:
>>> From: Kaito Cheng <chengkaitao@kylinos.cn>
>>>
>>> This series prepares for, and then updates, the list_for_each_entry()
>>> family so the common entry iterators cache their next or previous cursor
>>> before the loop body runs.
>>
>> Why in the world would we want to do that?
>>
>> The safe and non-safe variants have very distinct use cases and that is completely intentional.
>>
>> What we could improve maybe is the documentation, from my experience an astonishing large amount of people have misconceptions about the safe variants.
>>
>>> The first 13 patches open-code loops that intentionally depend on the
>>> old "derive the next entry from the current cursor at the end of the
>>> iteration" behaviour. These loops append work to the list being walked,
>>> restart traversal after dropping a lock, skip an entry consumed by the
>>> current iteration, or otherwise adjust the cursor in the loop body.
>>
>> Well I have to clearly reject the changes for subsystems/components I'm maintaining, that just looks horrible to me and I clearly don't see a good reason for that.
>
> Hi Christian and Andy Shevchenko,
>
> Thanks for taking a look. I would like to clarify the point you raised.
>
> The reason I started looking at this is the original motivation behind
> the _safe() variants. They exist because some users need to remove, move
> or otherwise consume the current entry while walking the list. In that
> case the next cursor has to be preserved before the loop body can modify
> the current entry.
>
> The unfortunate part is that this could not be expressed with the
> existing list_for_each_entry() interface without changing its calling
> convention. The _safe() variants had to grow an extra argument for the
> temporary cursor, and that is why we ended up with a separate family of
> macros.
>
> But conceptually, the distinction does not have to be exposed as two
> different iterator families forever. The difference is an implementation
> detail: whether the iterator keeps the next/previous cursor before the
> body runs. This series makes the common list_for_each_entry() iterators
> do that internally, so the safe and non-safe forms can effectively be
> folded together, or at least the need for a separate public _safe()
> interface becomes much weaker.
>
> There is also a usability issue with the current _safe() interface. The
> caller is forced to define a temporary cursor outside the macro and pass
> it in, even though almost all users never use that cursor directly. It is
> just boilerplate required by the macro implementation. I find that
> redundant and awkward: the temporary cursor is an internal detail of the
> iteration, but every caller has to spell it out.
>
> With the updated list_for_each_entry() implementation, that extra cursor
> can be kept inside the iterator itself. Callers that only want to walk
> the list, including callers that delete or consume the current entry, no
> longer need to carry an otherwise-unused temporary variable just to make
> the macro work.
Well the distinction between list_for_each_entry() and list_for_each_entry_safe() is *not* there because you need an extra variable to hold the next pointer, but because just 'iterating the list' and 'iterating the list while you modify it' are two distinct use cases.
Apart from the technical implications this also has some documentation value for the code using it.
What we could consider with C99 at hand is to have _safe() variants who uses a local hidden variable to hold the next element.
Or maybe come up with a better name instead of _safe() because people seem to misunderstand that quite often.
But mangling the two use cases together just because it is now technical possible is among the worst ideas I've ever heard.
Regards,
Christian.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-10 8:07 ` Christian König
@ 2026-06-10 8:18 ` Kaitao Cheng
2026-06-10 9:11 ` Christian König
0 siblings, 1 reply; 26+ messages in thread
From: Kaitao Cheng @ 2026-06-10 8:18 UTC (permalink / raw)
To: Christian König, Andy Shevchenko
Cc: Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Huang Rui,
Eddie James, Mark Brown, Maxime Coquelin, Alexandre Torgue,
Laxman Dewangan, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaito Cheng, Muchun Song, Philipp Reisner,
Lars Ellenberg, Christoph Böhmwalder, Jens Axboe,
Takashi Sakamoto, Andrzej Hajda, Jaroslav Kysela, Takashi Iwai
在 2026/6/10 16:07, Christian König 写道:
> On 6/10/26 08:14, Kaitao Cheng wrote:
>> 在 2026/6/9 18:33, Christian König 写道:
>>> On 6/9/26 08:13, Kaitao Cheng wrote:
>>>> From: Kaito Cheng <chengkaitao@kylinos.cn>
>>>>
>>>> This series prepares for, and then updates, the list_for_each_entry()
>>>> family so the common entry iterators cache their next or previous cursor
>>>> before the loop body runs.
>>>
>>> Why in the world would we want to do that?
>>>
>>> The safe and non-safe variants have very distinct use cases and that is completely intentional.
>>>
>>> What we could improve maybe is the documentation, from my experience an astonishing large amount of people have misconceptions about the safe variants.
>>>
>>>> The first 13 patches open-code loops that intentionally depend on the
>>>> old "derive the next entry from the current cursor at the end of the
>>>> iteration" behaviour. These loops append work to the list being walked,
>>>> restart traversal after dropping a lock, skip an entry consumed by the
>>>> current iteration, or otherwise adjust the cursor in the loop body.
>>>
>>> Well I have to clearly reject the changes for subsystems/components I'm maintaining, that just looks horrible to me and I clearly don't see a good reason for that.
>>
>> Hi Christian and Andy Shevchenko,
>>
>> Thanks for taking a look. I would like to clarify the point you raised.
>>
>> The reason I started looking at this is the original motivation behind
>> the _safe() variants. They exist because some users need to remove, move
>> or otherwise consume the current entry while walking the list. In that
>> case the next cursor has to be preserved before the loop body can modify
>> the current entry.
>>
>> The unfortunate part is that this could not be expressed with the
>> existing list_for_each_entry() interface without changing its calling
>> convention. The _safe() variants had to grow an extra argument for the
>> temporary cursor, and that is why we ended up with a separate family of
>> macros.
>>
>> But conceptually, the distinction does not have to be exposed as two
>> different iterator families forever. The difference is an implementation
>> detail: whether the iterator keeps the next/previous cursor before the
>> body runs. This series makes the common list_for_each_entry() iterators
>> do that internally, so the safe and non-safe forms can effectively be
>> folded together, or at least the need for a separate public _safe()
>> interface becomes much weaker.
>>
>> There is also a usability issue with the current _safe() interface. The
>> caller is forced to define a temporary cursor outside the macro and pass
>> it in, even though almost all users never use that cursor directly. It is
>> just boilerplate required by the macro implementation. I find that
>> redundant and awkward: the temporary cursor is an internal detail of the
>> iteration, but every caller has to spell it out.
>>
>> With the updated list_for_each_entry() implementation, that extra cursor
>> can be kept inside the iterator itself. Callers that only want to walk
>> the list, including callers that delete or consume the current entry, no
>> longer need to carry an otherwise-unused temporary variable just to make
>> the macro work.
>
> Well the distinction between list_for_each_entry() and list_for_each_entry_safe() is *not* there because you need an extra variable to hold the next pointer, but because just 'iterating the list' and 'iterating the list while you modify it' are two distinct use cases.
>
> Apart from the technical implications this also has some documentation value for the code using it.
>
> What we could consider with C99 at hand is to have _safe() variants who uses a local hidden variable to hold the next element.
>
> Or maybe come up with a better name instead of _safe() because people seem to misunderstand that quite often.
>
> But mangling the two use cases together just because it is now technical possible is among the worst ideas I've ever heard.
>
Should we revert to v1, or keep list_for_each_entry() and
list_for_each_entry_safe() as they are, close this thread, and make no
changes?
Link to v1:
https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@linux.dev/
Or do you have any better suggestions?
--
Thanks
Kaitao Cheng
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-10 8:18 ` Kaitao Cheng
@ 2026-06-10 9:11 ` Christian König
2026-06-10 15:02 ` Andy Shevchenko
0 siblings, 1 reply; 26+ messages in thread
From: Christian König @ 2026-06-10 9:11 UTC (permalink / raw)
To: Kaitao Cheng, Andy Shevchenko
Cc: Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Huang Rui,
Eddie James, Mark Brown, Maxime Coquelin, Alexandre Torgue,
Laxman Dewangan, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaito Cheng, Muchun Song, Philipp Reisner,
Lars Ellenberg, Christoph Böhmwalder, Jens Axboe,
Takashi Sakamoto, Andrzej Hajda, Jaroslav Kysela, Takashi Iwai
On 6/10/26 10:18, Kaitao Cheng wrote:
>
>
> 在 2026/6/10 16:07, Christian König 写道:
>> On 6/10/26 08:14, Kaitao Cheng wrote:
>>> 在 2026/6/9 18:33, Christian König 写道:
>>>> On 6/9/26 08:13, Kaitao Cheng wrote:
>>>>> From: Kaito Cheng <chengkaitao@kylinos.cn>
>>>>>
>>>>> This series prepares for, and then updates, the list_for_each_entry()
>>>>> family so the common entry iterators cache their next or previous cursor
>>>>> before the loop body runs.
>>>>
>>>> Why in the world would we want to do that?
>>>>
>>>> The safe and non-safe variants have very distinct use cases and that is completely intentional.
>>>>
>>>> What we could improve maybe is the documentation, from my experience an astonishing large amount of people have misconceptions about the safe variants.
>>>>
>>>>> The first 13 patches open-code loops that intentionally depend on the
>>>>> old "derive the next entry from the current cursor at the end of the
>>>>> iteration" behaviour. These loops append work to the list being walked,
>>>>> restart traversal after dropping a lock, skip an entry consumed by the
>>>>> current iteration, or otherwise adjust the cursor in the loop body.
>>>>
>>>> Well I have to clearly reject the changes for subsystems/components I'm maintaining, that just looks horrible to me and I clearly don't see a good reason for that.
>>>
>>> Hi Christian and Andy Shevchenko,
>>>
>>> Thanks for taking a look. I would like to clarify the point you raised.
>>>
>>> The reason I started looking at this is the original motivation behind
>>> the _safe() variants. They exist because some users need to remove, move
>>> or otherwise consume the current entry while walking the list. In that
>>> case the next cursor has to be preserved before the loop body can modify
>>> the current entry.
>>>
>>> The unfortunate part is that this could not be expressed with the
>>> existing list_for_each_entry() interface without changing its calling
>>> convention. The _safe() variants had to grow an extra argument for the
>>> temporary cursor, and that is why we ended up with a separate family of
>>> macros.
>>>
>>> But conceptually, the distinction does not have to be exposed as two
>>> different iterator families forever. The difference is an implementation
>>> detail: whether the iterator keeps the next/previous cursor before the
>>> body runs. This series makes the common list_for_each_entry() iterators
>>> do that internally, so the safe and non-safe forms can effectively be
>>> folded together, or at least the need for a separate public _safe()
>>> interface becomes much weaker.
>>>
>>> There is also a usability issue with the current _safe() interface. The
>>> caller is forced to define a temporary cursor outside the macro and pass
>>> it in, even though almost all users never use that cursor directly. It is
>>> just boilerplate required by the macro implementation. I find that
>>> redundant and awkward: the temporary cursor is an internal detail of the
>>> iteration, but every caller has to spell it out.
>>>
>>> With the updated list_for_each_entry() implementation, that extra cursor
>>> can be kept inside the iterator itself. Callers that only want to walk
>>> the list, including callers that delete or consume the current entry, no
>>> longer need to carry an otherwise-unused temporary variable just to make
>>> the macro work.
>>
>> Well the distinction between list_for_each_entry() and list_for_each_entry_safe() is *not* there because you need an extra variable to hold the next pointer, but because just 'iterating the list' and 'iterating the list while you modify it' are two distinct use cases.
>>
>> Apart from the technical implications this also has some documentation value for the code using it.
>>
>> What we could consider with C99 at hand is to have _safe() variants who uses a local hidden variable to hold the next element.
>>
>> Or maybe come up with a better name instead of _safe() because people seem to misunderstand that quite often.
>>
>> But mangling the two use cases together just because it is now technical possible is among the worst ideas I've ever heard.
>>
>
> Should we revert to v1, or keep list_for_each_entry() and
> list_for_each_entry_safe() as they are, close this thread, and make no
> changes?
>
> Link to v1:
> https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@linux.dev/
>
> Or do you have any better suggestions?
v1 looks perfectly reasonable to me.
You should just include some patches in the same patch set to actually use the new macros.
If you modify the files under drivers/dma-buf or drivers/gpu/drm/amd to use the new macro I'm happy to review that.
Regards,
Christian.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-10 6:14 ` Kaitao Cheng
2026-06-10 8:07 ` Christian König
@ 2026-06-10 14:43 ` Andy Shevchenko
1 sibling, 0 replies; 26+ messages in thread
From: Andy Shevchenko @ 2026-06-10 14:43 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Christian König, Thierry Reding, Jonathan Hunter,
Sowjanya Komatineni, Davidlohr Bueso, Paul E . McKenney,
Josh Triplett, Peter Zijlstra, Ingo Molnar, Will Deacon,
Boqun Feng, Liam Girdwood, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Neil Armstrong, Robert Foss, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Matthew Auld, Matthew Brost,
Waiman Long, drbd-dev, linux-block, linux1394-devel, dri-devel,
intel-gfx, linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaito Cheng,
Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Jaroslav Kysela, Takashi Iwai
On Wed, Jun 10, 2026 at 02:14:06PM +0800, Kaitao Cheng wrote:
> 在 2026/6/9 18:33, Christian König 写道:
> > On 6/9/26 08:13, Kaitao Cheng wrote:
> >>
> >> This series prepares for, and then updates, the list_for_each_entry()
> >> family so the common entry iterators cache their next or previous cursor
> >> before the loop body runs.
> >
> > Why in the world would we want to do that?
> >
> > The safe and non-safe variants have very distinct use cases and that is completely intentional.
> >
> > What we could improve maybe is the documentation, from my experience an astonishing large amount of people have misconceptions about the safe variants.
> >
> >> The first 13 patches open-code loops that intentionally depend on the
> >> old "derive the next entry from the current cursor at the end of the
> >> iteration" behaviour. These loops append work to the list being walked,
> >> restart traversal after dropping a lock, skip an entry consumed by the
> >> current iteration, or otherwise adjust the cursor in the loop body.
> >
> > Well I have to clearly reject the changes for subsystems/components I'm maintaining, that just looks horrible to me and I clearly don't see a good reason for that.
>
> Hi Christian and Andy Shevchenko,
>
> Thanks for taking a look. I would like to clarify the point you raised.
>
> The reason I started looking at this is the original motivation behind
> the _safe() variants. They exist because some users need to remove, move
> or otherwise consume the current entry while walking the list. In that
> case the next cursor has to be preserved before the loop body can modify
> the current entry.
>
> The unfortunate part is that this could not be expressed with the
> existing list_for_each_entry() interface without changing its calling
> convention. The _safe() variants had to grow an extra argument for the
> temporary cursor, and that is why we ended up with a separate family of
> macros.
>
> But conceptually, the distinction does not have to be exposed as two
> different iterator families forever. The difference is an implementation
> detail: whether the iterator keeps the next/previous cursor before the
> body runs. This series makes the common list_for_each_entry() iterators
> do that internally, so the safe and non-safe forms can effectively be
> folded together, or at least the need for a separate public _safe()
> interface becomes much weaker.
>
> There is also a usability issue with the current _safe() interface. The
> caller is forced to define a temporary cursor outside the macro and pass
> it in, even though almost all users never use that cursor directly. It is
> just boilerplate required by the macro implementation. I find that
> redundant and awkward: the temporary cursor is an internal detail of the
> iteration, but every caller has to spell it out.
Ah, I think the distinct macro families is that what we want.
But the hiding of the parameter can be done inside list_for_each_*_safe().
You can do a treewide change with coccinelle.
Sorry if I didn't get the whole idea from your previous contributions.
Note, even cases that would need a temporary cursor may be switched to
new list_for_each_*_safe(), see how PCI macros for iterating over resources
are implemented (include/linux/pci.h).
> With the updated list_for_each_entry() implementation, that extra cursor
> can be kept inside the iterator itself. Callers that only want to walk
> the list, including callers that delete or consume the current entry, no
> longer need to carry an otherwise-unused temporary variable just to make
> the macro work.
>
> >> The final patch changes include/linux/list.h to keep a private cursor in
> >> the common entry iterators while preserving the public macro interface.
> >> The safe variants remain available when callers need the temporary
> >> cursor explicitly or have stronger mutation requirements.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
2026-06-10 9:11 ` Christian König
@ 2026-06-10 15:02 ` Andy Shevchenko
0 siblings, 0 replies; 26+ messages in thread
From: Andy Shevchenko @ 2026-06-10 15:02 UTC (permalink / raw)
To: Christian König
Cc: Kaitao Cheng, Thierry Reding, Jonathan Hunter,
Sowjanya Komatineni, Davidlohr Bueso, Paul E . McKenney,
Josh Triplett, Peter Zijlstra, Ingo Molnar, Will Deacon,
Boqun Feng, Liam Girdwood, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Neil Armstrong, Robert Foss, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Matthew Auld, Matthew Brost,
Waiman Long, drbd-dev, linux-block, linux1394-devel, dri-devel,
intel-gfx, linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaito Cheng,
Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Jaroslav Kysela, Takashi Iwai
On Wed, Jun 10, 2026 at 11:11:34AM +0200, Christian König wrote:
> On 6/10/26 10:18, Kaitao Cheng wrote:
> > 在 2026/6/10 16:07, Christian König 写道:
...
> > Should we revert to v1, or keep list_for_each_entry() and
> > list_for_each_entry_safe() as they are, close this thread, and make no
> > changes?
> >
> > Link to v1:
> > https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@linux.dev/
> >
> > Or do you have any better suggestions?
>
> v1 looks perfectly reasonable to me.
But why not just hiding that once for all (in case they don't use the temporary
iterator)? Easy to automate, robust — everyone is happy?
> You should just include some patches in the same patch set to actually use
> the new macros.
>
> If you modify the files under drivers/dma-buf or drivers/gpu/drm/amd to use
> the new macro I'm happy to review that.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-06-10 15:02 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-09 6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 01/14] drbd: Open-code transfer log list walk Kaitao Cheng
2026-06-09 6:13 ` [PATCH v2 02/14] firewire: core: Open-code topology " Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
2026-06-09 7:00 ` Andy Shevchenko
2026-06-09 6:25 ` [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 06/14] drm/ttm: Open-code reservation " Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 07/14] spi: fsi: Open-code message transfer walk Kaitao Cheng
2026-06-09 7:02 ` Andy Shevchenko
2026-06-09 6:25 ` [PATCH v2 08/14] spi: stm32-ospi: " Kaitao Cheng
2026-06-09 6:25 ` [PATCH v2 09/14] spi: stm32-qspi: " Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk Kaitao Cheng
2026-06-09 6:38 ` [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder " Kaitao Cheng
2026-06-09 6:41 ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk Kaitao Cheng
2026-06-09 6:41 ` [PATCH v2 14/14] list: Cache cursors in entry iterators Kaitao Cheng
2026-06-09 6:47 ` [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Andy Shevchenko
2026-06-09 7:05 ` Andy Shevchenko
2026-06-09 10:33 ` Christian König
2026-06-10 6:14 ` Kaitao Cheng
2026-06-10 8:07 ` Christian König
2026-06-10 8:18 ` Kaitao Cheng
2026-06-10 9:11 ` Christian König
2026-06-10 15:02 ` Andy Shevchenko
2026-06-10 14:43 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox