Re: [PATCH v3 0/7] Prepare mutable list iterators to cache cursor state
From: Alexei Starovoitov
Date: Mon Jun 22 2026 - 01:30:07 EST
On Sun, Jun 21, 2026 at 9:06 PM Kaitao Cheng <kaitao.cheng@xxxxxxxxx> wrote:
>
> From: chengkaitao <chengkaitao@xxxxxxxxxx>
>
> The list_for_each*_safe() helpers are used when the loop body may remove
> the current entry. Their current interface, however, forces every caller
> to define a temporary cursor outside the macro and pass it in, even when
> the caller never uses that cursor directly. For most call sites this
> extra cursor is just boilerplate required by the macro implementation.
>
> This is awkward because the saved next pointer is an internal detail of
> the iteration. Callers that only remove or move the current entry do not
> need to spell it out.
>
> The _safe() suffix has also caused confusion. Christian Koenig pointed
> out that the name is easy to read as a thread-safe variant, especially
> for beginners, even though it only means that the iterator keeps enough
> state to tolerate removal of the current entry. He suggested _mutable()
> as a clearer description of what the loop permits.
>
> Add *_mutable() iterator variants for list, hlist and llist. The new
> helpers are variadic and support both forms. In the common case, the
> caller omits the temporary cursor and the macro creates a unique internal
> cursor with typeof(pos) and __UNIQUE_ID(). If a loop really needs an
> explicit temporary cursor, the caller can still pass it and the helper
> keeps the existing *_safe() behaviour.
>
> For example, a call site may use the shorter form:
>
> list_for_each_entry_mutable(pos, head, member)
>
> or keep the explicit temporary cursor form:
>
> list_for_each_entry_mutable(pos, tmp, head, member)
>
> The existing *_safe() helpers remain available for compatibility. This
> series only converts users in mm, block, kernel, init and io_uring. If
> this approach looks acceptable, the remaining users can be converted in
> follow-up series.
>
> Changes in v3 (Christian König, Andy Shevchenko):
> - Convert safe list walks to mutable iterators
>
> 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 v2:
> https://lore.kernel.org/all/20260609061347.93688-1-kaitao.cheng@xxxxxxxxx/
>
> Link to v1:
> https://lore.kernel.org/all/20260529082149.76764-1-kaitao.cheng@xxxxxxxxx/
>
> Kaitao Cheng (7):
> list: Add mutable iterator variants
> llist: Add mutable iterator variants
> mm: Use mutable list iterators
> block: Use mutable list iterators
> kernel: Use mutable list iterators
> initramfs: Use mutable list iterator
> io_uring: Use mutable list iterators
>
> block/bfq-iosched.c | 17 +-
> block/blk-cgroup.c | 12 +-
> block/blk-flush.c | 4 +-
> block/blk-iocost.c | 18 +-
> block/blk-mq.c | 8 +-
> block/blk-throttle.c | 4 +-
> block/kyber-iosched.c | 4 +-
> block/partitions/ldm.c | 8 +-
> block/sed-opal.c | 4 +-
> include/linux/list.h | 269 ++++++++++++++++++++++++----
> include/linux/llist.h | 81 +++++++--
> init/initramfs.c | 5 +-
> io_uring/cancel.c | 6 +-
> io_uring/poll.c | 3 +-
> io_uring/rw.c | 4 +-
> io_uring/timeout.c | 8 +-
> io_uring/uring_cmd.c | 3 +-
> kernel/audit_tree.c | 4 +-
> kernel/audit_watch.c | 16 +-
> kernel/auditfilter.c | 4 +-
> kernel/auditsc.c | 4 +-
> kernel/bpf/arena.c | 10 +-
> kernel/bpf/arraymap.c | 8 +-
> kernel/bpf/bpf_local_storage.c | 3 +-
> kernel/bpf/bpf_lru_list.c | 25 ++-
> kernel/bpf/btf.c | 18 +-
> kernel/bpf/cgroup.c | 7 +-
> kernel/bpf/cpumap.c | 4 +-
> kernel/bpf/devmap.c | 10 +-
> kernel/bpf/helpers.c | 8 +-
> kernel/bpf/local_storage.c | 4 +-
> kernel/bpf/memalloc.c | 16 +-
> kernel/bpf/offload.c | 8 +-
> kernel/bpf/states.c | 4 +-
> kernel/bpf/stream.c | 4 +-
> kernel/bpf/verifier.c | 6 +-
> kernel/cgroup/cgroup-v1.c | 4 +-
> kernel/cgroup/cgroup.c | 54 +++---
> kernel/cgroup/dmem.c | 12 +-
> kernel/cgroup/rdma.c | 8 +-
> kernel/events/core.c | 44 +++--
> kernel/events/uprobes.c | 12 +-
> kernel/exit.c | 8 +-
> kernel/fail_function.c | 4 +-
> kernel/gcov/clang.c | 4 +-
> kernel/irq_work.c | 4 +-
> kernel/kexec_core.c | 4 +-
> kernel/kprobes.c | 16 +-
> kernel/livepatch/core.c | 4 +-
> kernel/livepatch/core.h | 4 +-
> kernel/liveupdate/kho_block.c | 4 +-
> kernel/liveupdate/luo_flb.c | 4 +-
> kernel/locking/rwsem.c | 2 +-
> kernel/locking/test-ww_mutex.c | 2 +-
> kernel/module/main.c | 11 +-
> kernel/padata.c | 4 +-
> kernel/power/snapshot.c | 8 +-
> kernel/power/wakelock.c | 4 +-
> kernel/printk/printk.c | 11 +-
> kernel/ptrace.c | 4 +-
> kernel/rcu/rcutorture.c | 3 +-
> kernel/rcu/tasks.h | 9 +-
> kernel/rcu/tree.c | 6 +-
> kernel/resource.c | 4 +-
> kernel/sched/core.c | 4 +-
> kernel/sched/ext.c | 22 +--
> kernel/sched/fair.c | 28 +--
> kernel/sched/topology.c | 4 +-
> kernel/sched/wait.c | 4 +-
> kernel/seccomp.c | 4 +-
> kernel/signal.c | 11 +-
> kernel/smp.c | 4 +-
> kernel/taskstats.c | 8 +-
> kernel/time/clockevents.c | 6 +-
> kernel/time/clocksource.c | 4 +-
> kernel/time/posix-cpu-timers.c | 4 +-
> kernel/time/posix-timers.c | 3 +-
> kernel/torture.c | 3 +-
> kernel/trace/bpf_trace.c | 4 +-
> kernel/trace/ftrace.c | 49 +++--
> kernel/trace/ring_buffer.c | 25 ++-
> kernel/trace/trace.c | 12 +-
> kernel/trace/trace_dynevent.c | 6 +-
> kernel/trace/trace_dynevent.h | 5 +-
> kernel/trace/trace_events.c | 35 ++--
> kernel/trace/trace_events_filter.c | 4 +-
> kernel/trace/trace_events_hist.c | 8 +-
> kernel/trace/trace_events_trigger.c | 17 +-
> kernel/trace/trace_events_user.c | 16 +-
> kernel/trace/trace_stat.c | 4 +-
> kernel/user-return-notifier.c | 3 +-
> kernel/workqueue.c | 16 +-
> mm/backing-dev.c | 8 +-
> mm/balloon.c | 8 +-
> mm/cma.c | 4 +-
> mm/compaction.c | 4 +-
> mm/damon/core.c | 4 +-
> mm/damon/sysfs-schemes.c | 4 +-
> mm/dmapool.c | 4 +-
> mm/huge_memory.c | 8 +-
> mm/hugetlb.c | 56 +++---
> mm/hugetlb_vmemmap.c | 16 +-
> mm/khugepaged.c | 14 +-
> mm/kmemleak.c | 7 +-
> mm/ksm.c | 25 +--
> mm/list_lru.c | 4 +-
> mm/memcontrol-v1.c | 8 +-
> mm/memory-failure.c | 12 +-
> mm/memory-tiers.c | 4 +-
> mm/migrate.c | 23 ++-
> mm/mmu_notifier.c | 9 +-
> mm/page_alloc.c | 8 +-
> mm/page_reporting.c | 2 +-
> mm/percpu.c | 11 +-
> mm/pgtable-generic.c | 4 +-
> mm/rmap.c | 10 +-
> mm/shmem.c | 9 +-
> mm/slab_common.c | 14 +-
> mm/slub.c | 33 ++--
> mm/swapfile.c | 4 +-
> mm/userfaultfd.c | 12 +-
> mm/vmalloc.c | 24 +--
> mm/vmscan.c | 7 +-
> mm/zsmalloc.c | 4 +-
> 124 files changed, 875 insertions(+), 681 deletions(-)
Not sure what you were thinking, but this diff stat
is not landable.
pw-bot: cr