@@ -666,20 +666,33 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
666
666
667
667
/* Collect invalidated userptrs */
668
668
spin_lock (& vm -> userptr .invalidated_lock );
669
+ xe_assert (vm -> xe , list_empty (& vm -> userptr .repin_list ));
669
670
list_for_each_entry_safe (uvma , next , & vm -> userptr .invalidated ,
670
671
userptr .invalidate_link ) {
671
672
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 );
674
675
}
675
676
spin_unlock (& vm -> userptr .invalidated_lock );
676
677
677
- /* Pin and move to temporary list */
678
+ /* Pin and move to bind list */
678
679
list_for_each_entry_safe (uvma , next , & vm -> userptr .repin_list ,
679
680
userptr .repin_link ) {
680
681
err = xe_vma_userptr_pin_pages (uvma );
681
682
if (err == - EFAULT ) {
682
683
list_del_init (& uvma -> userptr .repin_link );
684
+ /*
685
+ * We might have already done the pin once already, but
686
+ * then had to retry before the re-bind happened, due
687
+ * some other condition in the caller, but in the
688
+ * meantime the userptr got dinged by the notifier such
689
+ * that we need to revalidate here, but this time we hit
690
+ * the EFAULT. In such a case make sure we remove
691
+ * ourselves from the rebind list to avoid going down in
692
+ * flames.
693
+ */
694
+ if (!list_empty (& uvma -> vma .combined_links .rebind ))
695
+ list_del_init (& uvma -> vma .combined_links .rebind );
683
696
684
697
/* Wait for pending binds */
685
698
xe_vm_lock (vm , false);
@@ -690,18 +703,30 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
690
703
err = xe_vm_invalidate_vma (& uvma -> vma );
691
704
xe_vm_unlock (vm );
692
705
if (err )
693
- return err ;
706
+ break ;
694
707
} else {
695
- if (err < 0 )
696
- return err ;
708
+ if (err )
709
+ break ;
697
710
698
711
list_del_init (& uvma -> userptr .repin_link );
699
712
list_move_tail (& uvma -> vma .combined_links .rebind ,
700
713
& vm -> rebind_list );
701
714
}
702
715
}
703
716
704
- return 0 ;
717
+ if (err ) {
718
+ down_write (& vm -> userptr .notifier_lock );
719
+ spin_lock (& vm -> userptr .invalidated_lock );
720
+ list_for_each_entry_safe (uvma , next , & vm -> userptr .repin_list ,
721
+ userptr .repin_link ) {
722
+ list_del_init (& uvma -> userptr .repin_link );
723
+ list_move_tail (& uvma -> userptr .invalidate_link ,
724
+ & vm -> userptr .invalidated );
725
+ }
726
+ spin_unlock (& vm -> userptr .invalidated_lock );
727
+ up_write (& vm -> userptr .notifier_lock );
728
+ }
729
+ return err ;
705
730
}
706
731
707
732
/**
@@ -1066,6 +1091,7 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
1066
1091
xe_assert (vm -> xe , vma -> gpuva .flags & XE_VMA_DESTROYED );
1067
1092
1068
1093
spin_lock (& vm -> userptr .invalidated_lock );
1094
+ xe_assert (vm -> xe , list_empty (& to_userptr_vma (vma )-> userptr .repin_link ));
1069
1095
list_del (& to_userptr_vma (vma )-> userptr .invalidate_link );
1070
1096
spin_unlock (& vm -> userptr .invalidated_lock );
1071
1097
} else if (!xe_vma_is_null (vma )) {
0 commit comments