From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: media: videobuf2: add dma_resv release-fence helper Date: Tue, 05 May 2026 11:08:37 +1000 Message-ID: In-Reply-To: <20260429195306.239666-2-mfritsche@reauktion.de> References: <3d8deeb15581b754e4c061d4c4a13657aa08bc3c.camel@ndufresne.ca> <20260429195306.239666-2-mfritsche@reauktion.de> X-Mailer: Claude Code Patch Reviewer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Patch Review **Fence leak on VB2_BUF_STATE_QUEUED (requeue) path** The signal path skips QUEUED state: ```c if (state != VB2_BUF_STATE_QUEUED) vb2_buffer_signal_release_fence(vb, state); ``` When a driver calls `vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED)` to requeue a buffer, `vb->release_fence` remains set but is never signaled. When the buffer is later re-submitted through `buf_queue`, the driver calls `vb2_buffer_attach_release_fence()` again, which hits: ```c if (WARN_ON(vb->release_fence)) return -EINVAL; ``` This leaves consumers permanently blocked on an unsignaled fence. The requeue case should either signal the old fence with an error before allowing a new one, or the `WARN_ON` should be replaced with cleanup logic that signals and releases the old fence. **No release_fence cleanup in `__vb2_queue_cancel`** `__vb2_queue_cancel()` reinitializes all buffers via `__vb2_dqbuf()` but never signals or puts any outstanding `release_fence`. After stop_streaming, the driver's `stop_streaming` callback should call `vb2_buffer_done(vb, VB2_BUF_STATE_ERROR)` for ACTIVE buffers, which would signal the fence. But if a driver fails to do so (the WARN_ON path at line 2210), the fallback `vb2_buffer_done(vb, VB2_BUF_STATE_ERROR)` does signal the fence, so that specific path is covered. However, the general buffer reinit loop (line 2255-2298) does not touch `release_fence` at all for any buffer state. A defensive `vb2_buffer_signal_release_fence(vb, VB2_BUF_STATE_ERROR)` call should be added there. **Unnecessary allocation when no planes have dbuf** ```c fence = kzalloc(sizeof(*fence), GFP_KERNEL); ... for (plane = 0; plane < vb->num_planes; plane++) { struct dma_buf *dbuf = vb->planes[plane].dbuf; if (!dbuf) continue; ... } ``` If no plane has a `dbuf` (e.g., MMAP-only buffers never exported), the fence is allocated, initialized, ref-counted, but attached to nothing. It will still be signaled in `vb2_buffer_done`, which is a no-op waste. Consider checking for any exportable plane before allocating: ```c bool has_dbuf = false; for (plane = 0; plane < vb->num_planes; plane++) { if (vb->planes[plane].dbuf) { has_dbuf = true; break; } } if (!has_dbuf) return 0; ``` **Reference counting is correct** The ref model is sound: - `dma_fence_init()` gives refcount 1 - `dma_resv_add_fence()` takes its own ref per plane - `dma_fence_get()` for `vb->release_fence` takes another - `dma_fence_put()` drops the initial ref - `vb2_buffer_signal_release_fence()` signals + puts the `vb->release_fence` ref The resv refs are dropped when fences are replaced or the resv is destroyed. **Signal path is IRQ-safe** `dma_fence_signal()` uses `spin_lock_irqsave` internally and `dma_fence_begin_signalling()` handles `in_atomic()`, so calling it from `vb2_buffer_done()` in IRQ context (e.g., hantro's IRQ handler) is safe. **Minor: verbose comment blocks** The multi-paragraph comment block at the top of the fence section (lines 1182-1193) duplicates the commit message. A 1-2 line comment would suffice in the source. --- --- Generated by Claude Code Patch Reviewer