@@ -1979,43 +1979,42 @@ static void svm_range_deferred_list_work(struct work_struct *work)
1979
1979
struct svm_range_list * svms ;
1980
1980
struct svm_range * prange ;
1981
1981
struct mm_struct * mm ;
1982
+ struct kfd_process * p ;
1982
1983
1983
1984
svms = container_of (work , struct svm_range_list , deferred_list_work );
1984
1985
pr_debug ("enter svms 0x%p\n" , svms );
1985
1986
1987
+ p = container_of (svms , struct kfd_process , svms );
1988
+ /* Avoid mm is gone when inserting mmu notifier */
1989
+ mm = get_task_mm (p -> lead_thread );
1990
+ if (!mm ) {
1991
+ pr_debug ("svms 0x%p process mm gone\n" , svms );
1992
+ return ;
1993
+ }
1994
+ retry :
1995
+ mmap_write_lock (mm );
1996
+
1997
+ /* Checking for the need to drain retry faults must be inside
1998
+ * mmap write lock to serialize with munmap notifiers.
1999
+ */
2000
+ if (unlikely (READ_ONCE (svms -> drain_pagefaults ))) {
2001
+ WRITE_ONCE (svms -> drain_pagefaults , false);
2002
+ mmap_write_unlock (mm );
2003
+ svm_range_drain_retry_fault (svms );
2004
+ goto retry ;
2005
+ }
2006
+
1986
2007
spin_lock (& svms -> deferred_list_lock );
1987
2008
while (!list_empty (& svms -> deferred_range_list )) {
1988
2009
prange = list_first_entry (& svms -> deferred_range_list ,
1989
2010
struct svm_range , deferred_list );
2011
+ list_del_init (& prange -> deferred_list );
1990
2012
spin_unlock (& svms -> deferred_list_lock );
2013
+
1991
2014
pr_debug ("prange 0x%p [0x%lx 0x%lx] op %d\n" , prange ,
1992
2015
prange -> start , prange -> last , prange -> work_item .op );
1993
2016
1994
- mm = prange -> work_item .mm ;
1995
- retry :
1996
- mmap_write_lock (mm );
1997
2017
mutex_lock (& svms -> lock );
1998
-
1999
- /* Checking for the need to drain retry faults must be in
2000
- * mmap write lock to serialize with munmap notifiers.
2001
- *
2002
- * Remove from deferred_list must be inside mmap write lock,
2003
- * otherwise, svm_range_list_lock_and_flush_work may hold mmap
2004
- * write lock, and continue because deferred_list is empty, then
2005
- * deferred_list handle is blocked by mmap write lock.
2006
- */
2007
- spin_lock (& svms -> deferred_list_lock );
2008
- if (unlikely (svms -> drain_pagefaults )) {
2009
- svms -> drain_pagefaults = false;
2010
- spin_unlock (& svms -> deferred_list_lock );
2011
- mutex_unlock (& svms -> lock );
2012
- mmap_write_unlock (mm );
2013
- svm_range_drain_retry_fault (svms );
2014
- goto retry ;
2015
- }
2016
- list_del_init (& prange -> deferred_list );
2017
- spin_unlock (& svms -> deferred_list_lock );
2018
-
2019
2018
mutex_lock (& prange -> migrate_mutex );
2020
2019
while (!list_empty (& prange -> child_list )) {
2021
2020
struct svm_range * pchild ;
@@ -2031,12 +2030,13 @@ static void svm_range_deferred_list_work(struct work_struct *work)
2031
2030
2032
2031
svm_range_handle_list_op (svms , prange );
2033
2032
mutex_unlock (& svms -> lock );
2034
- mmap_write_unlock (mm );
2035
2033
2036
2034
spin_lock (& svms -> deferred_list_lock );
2037
2035
}
2038
2036
spin_unlock (& svms -> deferred_list_lock );
2039
2037
2038
+ mmap_write_unlock (mm );
2039
+ mmput (mm );
2040
2040
pr_debug ("exit svms 0x%p\n" , svms );
2041
2041
}
2042
2042
@@ -2589,7 +2589,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
2589
2589
p = kfd_lookup_process_by_pasid (pasid );
2590
2590
if (!p ) {
2591
2591
pr_debug ("kfd process not founded pasid 0x%x\n" , pasid );
2592
- return - ESRCH ;
2592
+ return 0 ;
2593
2593
}
2594
2594
if (!p -> xnack_enabled ) {
2595
2595
pr_debug ("XNACK not enabled for pasid 0x%x\n" , pasid );
@@ -2600,10 +2600,12 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
2600
2600
2601
2601
pr_debug ("restoring svms 0x%p fault address 0x%llx\n" , svms , addr );
2602
2602
2603
+ /* p->lead_thread is available as kfd_process_wq_release flush the work
2604
+ * before releasing task ref.
2605
+ */
2603
2606
mm = get_task_mm (p -> lead_thread );
2604
2607
if (!mm ) {
2605
2608
pr_debug ("svms 0x%p failed to get mm\n" , svms );
2606
- r = - ESRCH ;
2607
2609
goto out ;
2608
2610
}
2609
2611
@@ -2730,6 +2732,13 @@ void svm_range_list_fini(struct kfd_process *p)
2730
2732
/* Ensure list work is finished before process is destroyed */
2731
2733
flush_work (& p -> svms .deferred_list_work );
2732
2734
2735
+ /*
2736
+ * Ensure no retry fault comes in afterwards, as page fault handler will
2737
+ * not find kfd process and take mm lock to recover fault.
2738
+ */
2739
+ svm_range_drain_retry_fault (& p -> svms );
2740
+
2741
+
2733
2742
list_for_each_entry_safe (prange , next , & p -> svms .list , list ) {
2734
2743
svm_range_unlink (prange );
2735
2744
svm_range_remove_notifier (prange );
0 commit comments