From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: drm/xe/userptr: Convert invalidation to two-pass MMU notifier Date: Tue, 03 Mar 2026 13:05:44 +1000 Message-ID: In-Reply-To: <20260302163248.105454-3-thomas.hellstrom@linux.intel.com> References: <20260302163248.105454-1-thomas.hellstrom@linux.intel.com> <20260302163248.105454-3-thomas.hellstrom@linux.intel.com> X-Mailer: Claude Code Patch Reviewer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Patch Review This patch converts the xe userptr invalidation to use the two-pass model from patch 1. The split into `xe_vma_userptr_invalidate_pass1` (enable SW signaling, check if fences are already signaled) and `xe_vma_userptr_do_inval` (wait for fences, invalidate TLB, unmap pages) is clean. **Bug: `static` local variable in `xe_vma_userptr_force_invalidate`:** ```c void xe_vma_userptr_force_invalidate(struct xe_userptr_vma *uvma) { static struct mmu_interval_notifier_finish *finish; ``` This `static` is almost certainly a bug. A local pointer to the finish struct should not be `static` - this serves no purpose and would be shared across all calls. If two threads call `xe_vma_userptr_force_invalidate` concurrently, the `static` variable creates a data race. This should be a plain local variable. (It appears this may have been introduced by the AI assistant.) **`finish_inuse` flag race consideration:** The `finish_inuse` flag is documented as protected by `vm::svm.gpusvm.notifier_lock`. In `xe_vma_userptr_invalidate_pass1`, it's checked and set under this lock. In `xe_vma_userptr_do_inval`, it's cleared under the lock in `xe_vma_userptr_invalidate_finish`. In the `xe_vma_userptr_invalidate_start` callback, the lock is held for the duration of the pass1 call. This looks correct. **Locking in `xe_vma_userptr_invalidate_finish`:** ```c down_write(&vm->svm.gpusvm.notifier_lock); xe_vma_userptr_do_inval(vm, uvma, true); up_write(&vm->svm.gpusvm.notifier_lock); ``` The finish callback takes the notifier_lock to protect the shared state. This is called from `mn_itree_finish_pass` which runs after the interval tree walk but before `mn_itree_inv_end`. The `mn_itree_inv_end` call releases the write side of `subscriptions->invalidate_seq`. So this should be safe - the finish pass runs in the same context as the original invalidation. **Question: What happens when `invalidate_start` returns `true` but `*p_finish` is NULL?** Looking at the `mn_itree_invalidate` code, when `ret` is true but `finish` is NULL, the notifier simply isn't added to the finish list. This is the correct "completed synchronously" path. --- --- Generated by Claude Code Patch Reviewer