From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: gpu: nova-core: fb: make sure to unregister SysmemFlush on boot failure Date: Sun, 12 Apr 2026 11:22:40 +1000 Message-ID: In-Reply-To: <20260409-fix-systemflush-v1-1-a1d6c968f17c@nvidia.com> References: <20260409-fix-systemflush-v1-1-a1d6c968f17c@nvidia.com> <20260409-fix-systemflush-v1-1-a1d6c968f17c@nvidia.com> X-Mailer: Claude Code Patch Reviewer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Patch Review **The bug being fixed is real and important.** Looking at `Gpu::new` (gpu.r= s:249-275), the `try_pin_init!` macro initializes fields sequentially. If a= ny field after `sysmem_flush` fails (e.g., `Falcon::new` at line 262, `Gsp:= :boot` at line 272), the already-initialized `SysmemFlush` is dropped. With= out a `Drop` impl, the DMA page is freed but the GPU register `NV_PFB_NISO_= FLUSH_SYSMEM_ADDR` still points to it. **Adding `Arc>` to `SysmemFlush`:** ```rust pub(crate) struct SysmemFlush { chipset: Chipset, device: ARef, + bar: Arc>, page: CoherentHandle, } ``` This is the right approach. `SysmemFlush` needs independent access to the B= AR for its `Drop` impl, since it can't rely on receiving a `&Bar0` referenc= e as a parameter during drop. The `Arc` clone is cheap and guarantees the `= Devres` outlives the `SysmemFlush` even if `Gpu`'s own `bar` field is= dropped first (Rust drops struct fields in declaration order, and `bar` is= declared before `sysmem_flush` in the `Gpu` struct). **The `Drop` implementation:** ```rust impl Drop for SysmemFlush { fn drop(&mut self) { let _ =3D self.bar.try_access_with(|bar| self.unregister(bar)); } } ``` This is correct. `try_access_with` returns `None` if the `Devres` has been = revoked (device unbound), in which case the hardware is already torn down a= nd unregistering is unnecessary. The `let _ =3D ...` appropriately discards= the `Option<()>` result. **The `registered_dma_handle !=3D 0` guard:** ```rust - } else { - // Another page has been registered after us for some reason -= warn as this is a bug. + } else if registered_dma_handle !=3D 0 { ``` This is a necessary change to avoid a spurious warning on the normal unbind= path. After `unbind()` calls `unregister()` (writing 0 to the register), t= he subsequent `Drop` would read 0, which doesn't match `self.page.dma_handl= e()`. Without this guard, it would incorrectly warn "attempt to unregister = a sysmem flush page that is not active." The new behavior correctly disting= uishes three cases: 1. Register matches our page =E2=86=92 unregister (write 0) 2. Register holds a different non-zero address =E2=86=92 warn (genuine bug) 3. Register is 0 =E2=86=92 silently do nothing (already cleaned up) **Minor observation (not blocking):** The doc comment update is good but co= uld be slightly more precise: ```rust +/// Users should call [`Self::unregister`] before unloading to ensure unre= gistering is infallible. +/// [`Drop`] performs a best-effort fallback using revocable BAR access. ``` The comment says "before unloading" but the actual call site is in `Gpu::un= bind`, which happens at unbind time. "Before unloading" could be confused w= ith module unload. A more precise wording might be "during unbind" but this= is a very minor documentation nit. **No issues with the `Gpu::new` call site change:** ```rust - sysmem_flush: SysmemFlush::register(pdev.as_ref(), bar, spec.c= hipset)?, + sysmem_flush: SysmemFlush::register( + pdev.as_ref(), + devres_bar.clone(), + bar, + spec.chipset, + )?, ``` The `devres_bar.clone()` correctly creates a new `Arc` reference for `Sysme= mFlush` to own. The original `devres_bar` is later moved into `bar: devres_= bar` (line 274). If initialization fails before that point, both `Arc`s are= dropped independently and the `Devres` refcount goes to zero, proper= ly cleaning up. **Overall: Clean, well-reasoned fix with no correctness issues.** --- Generated by Claude Code Patch Reviewer