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/buddy: Introduce __gpu_buddy_undo_splits() helper Date: Mon, 25 May 2026 19:06:37 +1000 Message-ID: In-Reply-To: <20260522092600.32818-4-francois.dugast@intel.com> References: <20260522092600.32818-1-francois.dugast@intel.com> <20260522092600.32818-4-francois.dugast@intel.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 **Correctness: Correct refactor, but one subtle behavioral change in `alloc= _from_freetree`.** The helper extracts the repeated pattern: ```c static void __gpu_buddy_undo_splits(struct gpu_buddy *mm, struct gpu_buddy_block *block) { struct gpu_buddy_block *buddy =3D __get_buddy(block); if (buddy && (gpu_buddy_block_is_free(block) && gpu_buddy_block_is_free(buddy))) { rbtree_remove(mm, block); __gpu_buddy_free(mm, block, false); } } ``` For the three sites in `__alloc_range_bias`, `gpu_buddy_offset_aligned_allo= cation`, and `__alloc_range`, this is a direct extraction =E2=80=94 those a= ll had the `if (buddy && ...)` guard already. **However**, in `alloc_from_freetree` (after patch 2's cleanup), the error = path was: ```c err_undo: rbtree_remove(mm, block); __gpu_buddy_free(mm, block, false); ``` =E2=80=94 i.e., **unconditional** `rbtree_remove` + `__gpu_buddy_free`. Now= it becomes: ```c err_undo: __gpu_buddy_undo_splits(mm, block); ``` which adds a **new guard** (`if buddy && both-free`). This is actually a ti= ghtening =E2=80=94 if the buddy is not free or doesn't exist, the function = now does nothing instead of unconditionally freeing. **Is this correct?** When `split_block()` fails in `alloc_from_freetree`, t= he block is still FREE (split didn't complete). After the first successful = split, the left child is marked free and the right child becomes `block` (v= ia `block =3D block->right`). The right child is also marked free by `split= _block()`. So after a failed split: - `block` is FREE (the split that failed didn't change its state) - `buddy` (left sibling) is FREE (created by the *previous* successful spli= t) So the guard `buddy && both-free` should be true in the normal case. But wh= at about the *first* iteration failure? Then `block` is the original block = from the tree =E2=80=94 it has no buddy from splitting (the `__get_buddy` m= ight return a pre-existing buddy). This seems safe: if there's no buddy or = the buddy isn't free, we just skip the undo, and `__gpu_buddy_free` would h= andle the block via the `mark_free` path at the bottom anyway. This is acceptable but the commit message could mention that `alloc_from_fr= eetree` gains the buddy guard it previously lacked. --- Generated by Claude Code Patch Reviewer