On Mon, Feb 12, 2024 at 12:48 PM Matt Bobrowski <mattbobrowski@xxxxxxxxxx> wrote: > > In numerous BPF programs, I've found myself needing to iterate over > some in-kernel generic data structure i.e. list_head, hlist_head, > rbtree, etc. The approach that I generally use to do this consists of > using bpf_loop(), container_of(), and BPF_CORE_READ(). The end result > of this approach is always rather messy as it's mostly implementation > specific and bound to a specific in-kernel type i.e. mount, dentry, > inode, etc. > > Recently, I came across the newly added bpf_for_each() open-coded > iterator, which could possibly help out a little with trivially > performing such iterations within BPF programs. However, looking into > the usage of this helper a little more, I realized that this too needs > to be backed by the new kfunc iterator framework > i.e. bpf_iter_##type##_new(), bpf_iter_##type##_destroy(), > bpf_iter_##type##_next(). So, in practice it seems like adopting this > approach to solve this specific iterator problem would lead us into a > situation where we'd be having to define iterator kfuncs for each > in-kernel type and respective field. > > Now having said this, I'm wondering whether anyone here has considered > possibly solving this iterator based problem a little more > generically? That is, by exposing a set of kfuncs that allow you to > iterate over a list_head, hlist_head, rbtree, etc, independent of an > underlying in-kernel type and similar to your *list_for_each*() based > helpers that you'd typically find for each of these in-kernel generic > data structures. If so, what were your findings when exploring this > problem space? If you're looking for read-only (aka untrusted_ptr_to_btf_id) access you can iterate link lists and everything else already without modifying the kernel. See list_for_each_entry() that is arena specific: https://lore.kernel.org/bpf/20240209040608.98927-19-alexei.starovoitov@xxxxxxxxx/ Same thing can be done today (no need to wait for arena) to walk kernel link lists. typeof and container_of would need to change to use bpf_core_cast. Then all pointers are untrusted and JIT-ed like inlined probe_read_kernel.