Re: [PATCH] bpf: make dmabuf iterator stay drained after NULL

From: Alexei Starovoitov

Date: Thu Nov 12 2026 - 16:35:20 EST


On Tue, Nov 10, 2026 at 04:51 AM Kang Chen <k.chen@xxxxxxxxxxxxxxxx> wrote:
> +/*
> + * The iterator state is one pointer wide because struct bpf_iter_dmabuf is
> + * part of the generated vmlinux.h ABI. Use an invalid pointer value as the
> + * "drained" sentinel instead of growing the state.
> + */
> +#define DMABUF_ITER_DONE ((struct dma_buf *)1L)

+1 to T.J.'s point re: DMABUF_ITER_START.
bpf_iter_kmem_cache_next() does it that way.
dma_buf_iter_next() leaves NULL at the end of the list. Let NULL mean
drained. Then no need for the 2nd store in next() and for the long
comments.


diff --git a/kernel/bpf/dmabuf_iter.c b/kernel/bpf/dmabuf_iter.c
index cd50024..1bef87b 100644
--- a/kernel/bpf/dmabuf_iter.c
+++ b/kernel/bpf/dmabuf_iter.c
@@ -156,6 +156,8 @@ struct bpf_iter_dmabuf_kern {
struct dma_buf *dmabuf;
} __aligned(8);

+#define DMABUF_ITER_START ((struct dma_buf *)1L)
+
__bpf_kfunc_start_defs();

__bpf_kfunc int bpf_iter_dmabuf_new(struct bpf_iter_dmabuf *it)
@@ -165,7 +167,7 @@ __bpf_kfunc int bpf_iter_dmabuf_new(struct bpf_iter_dmabuf *it)
BUILD_BUG_ON(sizeof(*kit) > sizeof(*it));
BUILD_BUG_ON(__alignof__(*kit) != __alignof__(*it));

- kit->dmabuf = NULL;
+ kit->dmabuf = DMABUF_ITER_START;
return 0;
}

@@ -173,10 +175,14 @@ __bpf_kfunc struct dma_buf *bpf_iter_dmabuf_next(struct bpf_iter_dmabuf *it)
{
struct bpf_iter_dmabuf_kern *kit = (void *)it;

- if (kit->dmabuf)
- kit->dmabuf = dma_buf_iter_next(kit->dmabuf);
- else
+ /* Once NULL is returned, next() has to keep returning NULL */
+ if (!kit->dmabuf)
+ return NULL;
+
+ if (kit->dmabuf == DMABUF_ITER_START)
kit->dmabuf = dma_buf_iter_begin();
+ else
+ kit->dmabuf = dma_buf_iter_next(kit->dmabuf);

return kit->dmabuf;
}
@@ -185,7 +191,7 @@ __bpf_kfunc void bpf_iter_dmabuf_destroy(struct bpf_iter_dmabuf *it)
{
struct bpf_iter_dmabuf_kern *kit = (void *)it;

- if (kit->dmabuf)
+ if (kit->dmabuf && kit->dmabuf != DMABUF_ITER_START)
dma_buf_put(kit->dmabuf);
}


Pls take T.J.'s selftest as patch 2 and tag the respin as
[PATCH bpf v2].

Also you sent fixes for css and scx_dsq.
bpf_iter_task_vma_next() has the same problem.
It doesn't hold mmap_lock between the calls since
commit bee9ef4a40a2 ("bpf: switch task_vma iterator from mmap_lock to per-VMA locks"):

Pls fix it too.

pw-bot: cr