6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Thomas Hellström commit d2ce8fcd778ee6d92748c92d23a56d4416c29d86 upstream. The VM's private BOs get their LRU position refreshed in bulk via ttm_lru_bulk_move_tail() on vm->lru_bulk_move, both after a successful non-LR exec and after the LR preempt-fence rebind worker runs. External objects (BOs potentially shared across VMs) are never added to that per-VM bulk move list, so their LRU position is never refreshed by either path. This makes external objects in active use look more evictable than they are. Add xe_vm_bump_lru(), which, under a single lru_lock critical section, performs the bulk move of the VM's private BOs and bumps each external object locked by the drm_exec transaction. Use it from both the non-LR exec path and the LR rebind worker, replacing the open-coded bulk move. Fixes: d490ecf57790 ("drm/xe: Rework xe_exec and the VM rebind worker to use the drm_exec helper") Cc: Matthew Auld Cc: Matthew Brost Cc: # v6.8+ Assisted-by: LLM Signed-off-by: Thomas Hellström Reviewed-by: Matthew Brost Reviewed-by: Matthew Auld Link: https://patch.msgid.link/20261012132607.21387-1-thomas.hellstrom@linux.intel.com (cherry picked from commit 324ba30cca180c2e1d02090743dd78ccb15b9e4a) Signed-off-by: Rodrigo Vivi Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/xe/xe_exec.c | 7 ++----- drivers/gpu/drm/xe/xe_vm.c | 31 ++++++++++++++++++++++++++++--- drivers/gpu/drm/xe/xe_vm.h | 2 ++ 3 files changed, 32 insertions(+), 8 deletions(-) --- a/drivers/gpu/drm/xe/xe_exec.c +++ b/drivers/gpu/drm/xe/xe_exec.c @@ -346,11 +346,8 @@ retry: xe_sched_job_push(job); xe_vm_reactivate_rebind(vm); - if (!err && !xe_vm_in_lr_mode(vm)) { - spin_lock(&xe->ttm.lru_lock); - ttm_lru_bulk_move_tail(&vm->lru_bulk_move); - spin_unlock(&xe->ttm.lru_lock); - } + if (!err && !xe_vm_in_lr_mode(vm)) + xe_vm_bump_lru(vm, exec); if (mode == EXEC_MODE_LR) xe_hw_engine_group_resume_faulting_lr_jobs(group); --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -376,6 +376,33 @@ int xe_vm_validate_rebind(struct xe_vm * return 0; } +/** + * xe_vm_bump_lru() - Bump the LRU position of BOs used by a submission + * @vm: The vm for which we are bumping LRUs. + * @exec: The struct drm_exec with the locked GEM objects. + * + * Move the VM's private BOs, and all external objects locked by @exec, + * to the LRU tail. Private BOs are moved in bulk using @vm's + * &xe_vm.lru_bulk_move. External objects, which may be shared with other + * VMs, are not part of that bulk move and are bumped individually. + */ +void xe_vm_bump_lru(struct xe_vm *vm, struct drm_exec *exec) +{ + spinlock_t *lru_lock = &vm->xe->ttm.lru_lock; + struct drm_gem_object *obj; + + spin_lock(lru_lock); + ttm_lru_bulk_move_tail(&vm->lru_bulk_move); + drm_exec_for_each_locked_object(exec, obj) { + if (!drm_gpuvm_is_extobj(&vm->gpuvm, obj)) + continue; + + ttm_bo_move_to_lru_tail(&gem_to_xe_bo(obj)->ttm); + cond_resched_lock(lru_lock); + } + spin_unlock(lru_lock); +} + static int xe_preempt_work_begin(struct drm_exec *exec, struct xe_vm *vm, bool *done) { @@ -524,9 +551,7 @@ retry: #undef retry_required - spin_lock(&vm->xe->ttm.lru_lock); - ttm_lru_bulk_move_tail(&vm->lru_bulk_move); - spin_unlock(&vm->xe->ttm.lru_lock); + xe_vm_bump_lru(vm, &exec); /* Point of no return. */ arm_preempt_fences(vm, &preempt_fences); --- a/drivers/gpu/drm/xe/xe_vm.h +++ b/drivers/gpu/drm/xe/xe_vm.h @@ -265,6 +265,8 @@ int xe_vm_lock_vma(struct drm_exec *exec int xe_vm_validate_rebind(struct xe_vm *vm, struct drm_exec *exec, unsigned int num_fences); +void xe_vm_bump_lru(struct xe_vm *vm, struct drm_exec *exec); + struct dma_fence *xe_vm_bind_kernel_bo(struct xe_vm *vm, struct xe_bo *bo, struct xe_exec_queue *q, u64 addr, enum xe_cache_level cache_lvl);