Skip to content

Commit e043dc1

Browse files
matt-auldrodrigovivi
authored andcommitted
drm/xe/userptr: restore invalidation list on error
On error restore anything still on the pin_list back to the invalidation list on error. For the actual pin, so long as the vma is tracked on either list it should get picked up on the next pin, however it looks possible for the vma to get nuked but still be present on this per vm pin_list leading to corruption. An alternative might be then to instead just remove the link when destroying the vma. v2: - Also add some asserts. - Keep the overzealous locking so that we are consistent with the docs; updating the docs and related bits will be done as a follow up. Fixes: ed2bdf3 ("drm/xe/vm: Subclass userptr vmas") Suggested-by: Matthew Brost <[email protected]> Signed-off-by: Matthew Auld <[email protected]> Cc: Thomas Hellström <[email protected]> Cc: <[email protected]> # v6.8+ Reviewed-by: Matthew Brost <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Lucas De Marchi <[email protected]> (cherry picked from commit 4e37e92) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent d082ecb commit e043dc1

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

drivers/gpu/drm/xe/xe_vm.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -666,15 +666,16 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
666666

667667
/* Collect invalidated userptrs */
668668
spin_lock(&vm->userptr.invalidated_lock);
669+
xe_assert(vm->xe, list_empty(&vm->userptr.repin_list));
669670
list_for_each_entry_safe(uvma, next, &vm->userptr.invalidated,
670671
userptr.invalidate_link) {
671672
list_del_init(&uvma->userptr.invalidate_link);
672-
list_move_tail(&uvma->userptr.repin_link,
673-
&vm->userptr.repin_list);
673+
list_add_tail(&uvma->userptr.repin_link,
674+
&vm->userptr.repin_list);
674675
}
675676
spin_unlock(&vm->userptr.invalidated_lock);
676677

677-
/* Pin and move to temporary list */
678+
/* Pin and move to bind list */
678679
list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
679680
userptr.repin_link) {
680681
err = xe_vma_userptr_pin_pages(uvma);
@@ -690,18 +691,30 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
690691
err = xe_vm_invalidate_vma(&uvma->vma);
691692
xe_vm_unlock(vm);
692693
if (err)
693-
return err;
694+
break;
694695
} else {
695-
if (err < 0)
696-
return err;
696+
if (err)
697+
break;
697698

698699
list_del_init(&uvma->userptr.repin_link);
699700
list_move_tail(&uvma->vma.combined_links.rebind,
700701
&vm->rebind_list);
701702
}
702703
}
703704

704-
return 0;
705+
if (err) {
706+
down_write(&vm->userptr.notifier_lock);
707+
spin_lock(&vm->userptr.invalidated_lock);
708+
list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
709+
userptr.repin_link) {
710+
list_del_init(&uvma->userptr.repin_link);
711+
list_move_tail(&uvma->userptr.invalidate_link,
712+
&vm->userptr.invalidated);
713+
}
714+
spin_unlock(&vm->userptr.invalidated_lock);
715+
up_write(&vm->userptr.notifier_lock);
716+
}
717+
return err;
705718
}
706719

707720
/**
@@ -1066,6 +1079,7 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
10661079
xe_assert(vm->xe, vma->gpuva.flags & XE_VMA_DESTROYED);
10671080

10681081
spin_lock(&vm->userptr.invalidated_lock);
1082+
xe_assert(vm->xe, list_empty(&to_userptr_vma(vma)->userptr.repin_link));
10691083
list_del(&to_userptr_vma(vma)->userptr.invalidate_link);
10701084
spin_unlock(&vm->userptr.invalidated_lock);
10711085
} else if (!xe_vma_is_null(vma)) {

0 commit comments

Comments
 (0)