On 6/22/26 07:28, Alexei Starovoitov wrote: > On Sun, Jun 21, 2026 at 9:06 PM Kaitao Cheng <[email protected]> wrote: >> >> From: chengkaitao <[email protected]> >> >> 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/[email protected]/ >> >> Link to v1: >> https://lore.kernel.org/all/[email protected]/ >> >> 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.
Agreed. If we decide we want this, I guess we should target per-subsystem conversions. If this goes through the MM tree, I would even appreciate doing this on a per-MM component granularity. (unless we have some magic "Linus converts all of them" script, which I doubt we will have) Is there a way forward to replace list_for_each_*_safe entirely, possibly just reusing the old name but simply the parameter? -- Cheers, David
