From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: rust: gpuvm: add GpuVm::obtain() Date: Sun, 12 Apr 2026 11:16:41 +1000 Message-ID: In-Reply-To: <20260409-gpuvm-rust-v6-2-b16e6ada7261@google.com> References: <20260409-gpuvm-rust-v6-0-b16e6ada7261@google.com> <20260409-gpuvm-rust-v6-2-b16e6ada7261@google.com> X-Mailer: Claude Code Patch Reviewer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Patch Review Introduces `GpuVmBo`, `GpuVmBoAlloc`, and the `obtain()` flow for creating/looking-up VM-BO associations. **Observations:** 1. **`dma_resv_lock` return value not checked in `obtain()`**: ```rust unsafe { bindings::dma_resv_lock(resv_lock, ptr::null_mut()) }; ``` `dma_resv_lock()` returns `int` (can return `-EALREADY` when ctx is NULL and the lock is already held, or 0 on success). In this case, `ctx` is NULL, so `-EDEADLK` won't occur, but the return value is still silently discarded. While in practice with a NULL context the call should always succeed (or indicate the lock is already held, which for a ww_mutex with NULL ctx shouldn't happen), it would be more robust to at least debug-assert the return value is 0. The TODO comment acknowledges this needs a proper lock guard, but the unchecked return is worth noting. 2. **`ALLOC_FN` / `FREE_FN` const evaluation**: The clever const-time comparison of `Layout::new::()` vs `Layout::new::()` to decide whether a custom allocator is needed is elegant. When `T::VmBoData` is a ZST with no extra alignment, the default C `kzalloc(sizeof(drm_gpuvm_bo))` is used, avoiding unnecessary indirection. 3. **`vm_bo_alloc` returns null on allocation failure**: ```rust unsafe extern "C" fn vm_bo_alloc() -> *mut bindings::drm_gpuvm_bo { let raw_ptr = KBox::::new_uninit(GFP_KERNEL | __GFP_ZERO) .map(KBox::into_raw) .unwrap_or(ptr::null_mut()); raw_ptr.cast() } ``` Returning null on allocation failure is correct -- the C code checks for NULL from `vm_bo_alloc`. 4. **`GpuVmBoAlloc::new` calls `drm_gpuvm_bo_create` then initializes `data`**: If `value.__pinned_init()` fails (which can't actually fail since it uses the infallible `PinInit` protocol via `let Ok(()) = ...`), the data wouldn't be initialized but the `drm_gpuvm_bo` was already created. The `let Ok(()) = ...` pattern is the right approach for infallible initializers. 5. **`GpuVmBoAlloc::obtain` race condition fix**: The v6 changelog mentions calling `extobj_add` even when `ptr != me` (i.e., an existing VM-BO was returned). This is correct: ```rust // Note that we must call `extobj_add` even if `ptr != me` to avoid a race condition ``` Without this, two concurrent `obtain()` calls could result in the first thread's VM-BO being used before its `extobj_add` completes. 6. **`GpuVmBoAlloc` Drop impl**: Uses `drm_gpuvm_bo_put_deferred` which is correct for immediate mode, matching the `dec_ref` implementation. --- Generated by Claude Code Patch Reviewer