Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Add open coded dmabuf iterator

This open coded iterator allows for more flexibility when creating BPF
programs. It can support output in formats other than text. With an open
coded iterator, a single BPF program can traverse multiple kernel data
structures (now including dmabufs), allowing for more efficient analysis
of kernel data compared to multiple reads from procfs, sysfs, or
multiple traditional BPF iterator invocations.

Signed-off-by: T.J. Mercier <tjmercier@google.com>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20250522230429.941193-4-tjmercier@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

T.J. Mercier and committed by
Alexei Starovoitov
6eab7ac7 76ea9553

+53
+48
kernel/bpf/dmabuf_iter.c
··· 100 100 } 101 101 102 102 late_initcall(dmabuf_iter_init); 103 + 104 + struct bpf_iter_dmabuf { 105 + /* 106 + * opaque iterator state; having __u64 here allows to preserve correct 107 + * alignment requirements in vmlinux.h, generated from BTF 108 + */ 109 + __u64 __opaque[1]; 110 + } __aligned(8); 111 + 112 + /* Non-opaque version of bpf_iter_dmabuf */ 113 + struct bpf_iter_dmabuf_kern { 114 + struct dma_buf *dmabuf; 115 + } __aligned(8); 116 + 117 + __bpf_kfunc_start_defs(); 118 + 119 + __bpf_kfunc int bpf_iter_dmabuf_new(struct bpf_iter_dmabuf *it) 120 + { 121 + struct bpf_iter_dmabuf_kern *kit = (void *)it; 122 + 123 + BUILD_BUG_ON(sizeof(*kit) > sizeof(*it)); 124 + BUILD_BUG_ON(__alignof__(*kit) != __alignof__(*it)); 125 + 126 + kit->dmabuf = NULL; 127 + return 0; 128 + } 129 + 130 + __bpf_kfunc struct dma_buf *bpf_iter_dmabuf_next(struct bpf_iter_dmabuf *it) 131 + { 132 + struct bpf_iter_dmabuf_kern *kit = (void *)it; 133 + 134 + if (kit->dmabuf) 135 + kit->dmabuf = dma_buf_iter_next(kit->dmabuf); 136 + else 137 + kit->dmabuf = dma_buf_iter_begin(); 138 + 139 + return kit->dmabuf; 140 + } 141 + 142 + __bpf_kfunc void bpf_iter_dmabuf_destroy(struct bpf_iter_dmabuf *it) 143 + { 144 + struct bpf_iter_dmabuf_kern *kit = (void *)it; 145 + 146 + if (kit->dmabuf) 147 + dma_buf_put(kit->dmabuf); 148 + } 149 + 150 + __bpf_kfunc_end_defs();
+5
kernel/bpf/helpers.c
··· 3386 3386 BTF_ID_FLAGS(func, bpf_copy_from_user_str_dynptr, KF_SLEEPABLE) 3387 3387 BTF_ID_FLAGS(func, bpf_copy_from_user_task_dynptr, KF_SLEEPABLE | KF_TRUSTED_ARGS) 3388 3388 BTF_ID_FLAGS(func, bpf_copy_from_user_task_str_dynptr, KF_SLEEPABLE | KF_TRUSTED_ARGS) 3389 + #ifdef CONFIG_DMA_SHARED_BUFFER 3390 + BTF_ID_FLAGS(func, bpf_iter_dmabuf_new, KF_ITER_NEW | KF_SLEEPABLE) 3391 + BTF_ID_FLAGS(func, bpf_iter_dmabuf_next, KF_ITER_NEXT | KF_RET_NULL | KF_SLEEPABLE) 3392 + BTF_ID_FLAGS(func, bpf_iter_dmabuf_destroy, KF_ITER_DESTROY | KF_SLEEPABLE) 3393 + #endif 3389 3394 BTF_KFUNCS_END(common_btf_ids) 3390 3395 3391 3396 static const struct btf_kfunc_id_set common_kfunc_set = {