@@ -442,10 +442,10 @@ svm_migrate_vma_to_vram(struct kfd_node *node, struct svm_range *prange,
442442 goto out_free ;
443443 }
444444 if (cpages != npages )
445- pr_debug ("partial migration, 0x%lx/0x%llx pages collected \n" ,
445+ pr_debug ("partial migration, 0x%lx/0x%llx pages migrated \n" ,
446446 cpages , npages );
447447 else
448- pr_debug ("0x%lx pages collected \n" , cpages );
448+ pr_debug ("0x%lx pages migrated \n" , cpages );
449449
450450 r = svm_migrate_copy_to_vram (node , prange , & migrate , & mfence , scratch , ttm_res_offset );
451451 migrate_vma_pages (& migrate );
@@ -479,8 +479,6 @@ svm_migrate_vma_to_vram(struct kfd_node *node, struct svm_range *prange,
479479 * svm_migrate_ram_to_vram - migrate svm range from system to device
480480 * @prange: range structure
481481 * @best_loc: the device to migrate to
482- * @start_mgr: start page to migrate
483- * @last_mgr: last page to migrate
484482 * @mm: the process mm structure
485483 * @trigger: reason of migration
486484 *
@@ -491,7 +489,6 @@ svm_migrate_vma_to_vram(struct kfd_node *node, struct svm_range *prange,
491489 */
492490static int
493491svm_migrate_ram_to_vram (struct svm_range * prange , uint32_t best_loc ,
494- unsigned long start_mgr , unsigned long last_mgr ,
495492 struct mm_struct * mm , uint32_t trigger )
496493{
497494 unsigned long addr , start , end ;
@@ -501,30 +498,23 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
501498 unsigned long cpages = 0 ;
502499 long r = 0 ;
503500
504- if (! best_loc ) {
505- pr_debug ("svms 0x%p [0x%lx 0x%lx] migrate to sys ram \n" ,
506- prange -> svms , start_mgr , last_mgr );
501+ if (prange -> actual_loc == best_loc ) {
502+ pr_debug ("svms 0x%p [0x%lx 0x%lx] already on best_loc 0x%x \n" ,
503+ prange -> svms , prange -> start , prange -> last , best_loc );
507504 return 0 ;
508505 }
509506
510- if (start_mgr < prange -> start || last_mgr > prange -> last ) {
511- pr_debug ("range [0x%lx 0x%lx] out prange [0x%lx 0x%lx]\n" ,
512- start_mgr , last_mgr , prange -> start , prange -> last );
513- return - EFAULT ;
514- }
515-
516507 node = svm_range_get_node_by_id (prange , best_loc );
517508 if (!node ) {
518509 pr_debug ("failed to get kfd node by id 0x%x\n" , best_loc );
519510 return - ENODEV ;
520511 }
521512
522- pr_debug ("svms 0x%p [0x%lx 0x%lx] in [0x%lx 0x%lx] to gpu 0x%x\n" ,
523- prange -> svms , start_mgr , last_mgr , prange -> start , prange -> last ,
524- best_loc );
513+ pr_debug ("svms 0x%p [0x%lx 0x%lx] to gpu 0x%x\n" , prange -> svms ,
514+ prange -> start , prange -> last , best_loc );
525515
526- start = start_mgr << PAGE_SHIFT ;
527- end = (last_mgr + 1 ) << PAGE_SHIFT ;
516+ start = prange -> start << PAGE_SHIFT ;
517+ end = (prange -> last + 1 ) << PAGE_SHIFT ;
528518
529519 r = svm_range_vram_node_new (node , prange , true);
530520 if (r ) {
@@ -554,11 +544,8 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
554544
555545 if (cpages ) {
556546 prange -> actual_loc = best_loc ;
557- prange -> vram_pages = prange -> vram_pages + cpages ;
558- } else if (!prange -> actual_loc ) {
559- /* if no page migrated and all pages from prange are at
560- * sys ram drop svm_bo got from svm_range_vram_node_new
561- */
547+ svm_range_dma_unmap (prange );
548+ } else {
562549 svm_range_vram_node_free (prange );
563550 }
564551
@@ -676,8 +663,9 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
676663 * Context: Process context, caller hold mmap read lock, prange->migrate_mutex
677664 *
678665 * Return:
666+ * 0 - success with all pages migrated
679667 * negative values - indicate error
680- * positive values or zero - number of pages got migrated
668+ * positive values - partial migration, number of pages not migrated
681669 */
682670static long
683671svm_migrate_vma_to_ram (struct kfd_node * node , struct svm_range * prange ,
@@ -688,7 +676,6 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
688676 uint64_t npages = (end - start ) >> PAGE_SHIFT ;
689677 unsigned long upages = npages ;
690678 unsigned long cpages = 0 ;
691- unsigned long mpages = 0 ;
692679 struct amdgpu_device * adev = node -> adev ;
693680 struct kfd_process_device * pdd ;
694681 struct dma_fence * mfence = NULL ;
@@ -738,10 +725,10 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
738725 goto out_free ;
739726 }
740727 if (cpages != npages )
741- pr_debug ("partial migration, 0x%lx/0x%llx pages collected \n" ,
728+ pr_debug ("partial migration, 0x%lx/0x%llx pages migrated \n" ,
742729 cpages , npages );
743730 else
744- pr_debug ("0x%lx pages collected \n" , cpages );
731+ pr_debug ("0x%lx pages migrated \n" , cpages );
745732
746733 r = svm_migrate_copy_to_ram (adev , prange , & migrate , & mfence ,
747734 scratch , npages );
@@ -764,21 +751,17 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
764751 kvfree (buf );
765752out :
766753 if (!r && cpages ) {
767- mpages = cpages - upages ;
768754 pdd = svm_range_get_pdd_by_node (prange , node );
769755 if (pdd )
770- WRITE_ONCE (pdd -> page_out , pdd -> page_out + mpages );
756+ WRITE_ONCE (pdd -> page_out , pdd -> page_out + cpages );
771757 }
772-
773- return r ? r : mpages ;
758+ return r ? r : upages ;
774759}
775760
776761/**
777762 * svm_migrate_vram_to_ram - migrate svm range from device to system
778763 * @prange: range structure
779764 * @mm: process mm, use current->mm if NULL
780- * @start_mgr: start page need be migrated to sys ram
781- * @last_mgr: last page need be migrated to sys ram
782765 * @trigger: reason of migration
783766 * @fault_page: is from vmf->page, svm_migrate_to_ram(), this is CPU page fault callback
784767 *
@@ -788,41 +771,33 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
788771 * 0 - OK, otherwise error code
789772 */
790773int svm_migrate_vram_to_ram (struct svm_range * prange , struct mm_struct * mm ,
791- unsigned long start_mgr , unsigned long last_mgr ,
792774 uint32_t trigger , struct page * fault_page )
793775{
794776 struct kfd_node * node ;
795777 struct vm_area_struct * vma ;
796778 unsigned long addr ;
797779 unsigned long start ;
798780 unsigned long end ;
799- unsigned long mpages = 0 ;
781+ unsigned long upages = 0 ;
800782 long r = 0 ;
801783
802- /* this pragne has no any vram page to migrate to sys ram */
803784 if (!prange -> actual_loc ) {
804785 pr_debug ("[0x%lx 0x%lx] already migrated to ram\n" ,
805786 prange -> start , prange -> last );
806787 return 0 ;
807788 }
808789
809- if (start_mgr < prange -> start || last_mgr > prange -> last ) {
810- pr_debug ("range [0x%lx 0x%lx] out prange [0x%lx 0x%lx]\n" ,
811- start_mgr , last_mgr , prange -> start , prange -> last );
812- return - EFAULT ;
813- }
814-
815790 node = svm_range_get_node_by_id (prange , prange -> actual_loc );
816791 if (!node ) {
817792 pr_debug ("failed to get kfd node by id 0x%x\n" , prange -> actual_loc );
818793 return - ENODEV ;
819794 }
820795 pr_debug ("svms 0x%p prange 0x%p [0x%lx 0x%lx] from gpu 0x%x to ram\n" ,
821- prange -> svms , prange , start_mgr , last_mgr ,
796+ prange -> svms , prange , prange -> start , prange -> last ,
822797 prange -> actual_loc );
823798
824- start = start_mgr << PAGE_SHIFT ;
825- end = (last_mgr + 1 ) << PAGE_SHIFT ;
799+ start = prange -> start << PAGE_SHIFT ;
800+ end = (prange -> last + 1 ) << PAGE_SHIFT ;
826801
827802 for (addr = start ; addr < end ;) {
828803 unsigned long next ;
@@ -841,21 +816,14 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
841816 pr_debug ("failed %ld to migrate prange %p\n" , r , prange );
842817 break ;
843818 } else {
844- mpages += r ;
819+ upages += r ;
845820 }
846821 addr = next ;
847822 }
848823
849- if (r >= 0 ) {
850- prange -> vram_pages -= mpages ;
851-
852- /* prange does not have vram page set its actual_loc to system
853- * and drop its svm_bo ref
854- */
855- if (prange -> vram_pages == 0 && prange -> ttm_res ) {
856- prange -> actual_loc = 0 ;
857- svm_range_vram_node_free (prange );
858- }
824+ if (r >= 0 && !upages ) {
825+ svm_range_vram_node_free (prange );
826+ prange -> actual_loc = 0 ;
859827 }
860828
861829 return r < 0 ? r : 0 ;
@@ -865,23 +833,17 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
865833 * svm_migrate_vram_to_vram - migrate svm range from device to device
866834 * @prange: range structure
867835 * @best_loc: the device to migrate to
868- * @start: start page need be migrated to sys ram
869- * @last: last page need be migrated to sys ram
870836 * @mm: process mm, use current->mm if NULL
871837 * @trigger: reason of migration
872838 *
873839 * Context: Process context, caller hold mmap read lock, svms lock, prange lock
874840 *
875- * migrate all vram pages in prange to sys ram, then migrate
876- * [start, last] pages from sys ram to gpu node best_loc.
877- *
878841 * Return:
879842 * 0 - OK, otherwise error code
880843 */
881844static int
882845svm_migrate_vram_to_vram (struct svm_range * prange , uint32_t best_loc ,
883- unsigned long start , unsigned long last ,
884- struct mm_struct * mm , uint32_t trigger )
846+ struct mm_struct * mm , uint32_t trigger )
885847{
886848 int r , retries = 3 ;
887849
@@ -893,30 +855,25 @@ svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc,
893855 pr_debug ("from gpu 0x%x to gpu 0x%x\n" , prange -> actual_loc , best_loc );
894856
895857 do {
896- r = svm_migrate_vram_to_ram (prange , mm , prange -> start , prange -> last ,
897- trigger , NULL );
858+ r = svm_migrate_vram_to_ram (prange , mm , trigger , NULL );
898859 if (r )
899860 return r ;
900861 } while (prange -> actual_loc && -- retries );
901862
902863 if (prange -> actual_loc )
903864 return - EDEADLK ;
904865
905- return svm_migrate_ram_to_vram (prange , best_loc , start , last , mm , trigger );
866+ return svm_migrate_ram_to_vram (prange , best_loc , mm , trigger );
906867}
907868
908869int
909870svm_migrate_to_vram (struct svm_range * prange , uint32_t best_loc ,
910- unsigned long start , unsigned long last ,
911- struct mm_struct * mm , uint32_t trigger )
871+ struct mm_struct * mm , uint32_t trigger )
912872{
913- if (!prange -> actual_loc || prange -> actual_loc == best_loc )
914- return svm_migrate_ram_to_vram (prange , best_loc , start , last ,
915- mm , trigger );
916-
873+ if (!prange -> actual_loc )
874+ return svm_migrate_ram_to_vram (prange , best_loc , mm , trigger );
917875 else
918- return svm_migrate_vram_to_vram (prange , best_loc , start , last ,
919- mm , trigger );
876+ return svm_migrate_vram_to_vram (prange , best_loc , mm , trigger );
920877
921878}
922879
@@ -932,9 +889,10 @@ svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
932889 */
933890static vm_fault_t svm_migrate_to_ram (struct vm_fault * vmf )
934891{
935- unsigned long start , last , size ;
936892 unsigned long addr = vmf -> address ;
937893 struct svm_range_bo * svm_bo ;
894+ enum svm_work_list_ops op ;
895+ struct svm_range * parent ;
938896 struct svm_range * prange ;
939897 struct kfd_process * p ;
940898 struct mm_struct * mm ;
@@ -971,31 +929,51 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
971929
972930 mutex_lock (& p -> svms .lock );
973931
974- prange = svm_range_from_addr (& p -> svms , addr , NULL );
932+ prange = svm_range_from_addr (& p -> svms , addr , & parent );
975933 if (!prange ) {
976934 pr_debug ("failed get range svms 0x%p addr 0x%lx\n" , & p -> svms , addr );
977935 r = - EFAULT ;
978936 goto out_unlock_svms ;
979937 }
980938
981- mutex_lock (& prange -> migrate_mutex );
939+ mutex_lock (& parent -> migrate_mutex );
940+ if (prange != parent )
941+ mutex_lock_nested (& prange -> migrate_mutex , 1 );
982942
983943 if (!prange -> actual_loc )
984944 goto out_unlock_prange ;
985945
986- /* Align migration range start and size to granularity size */
987- size = 1UL << prange -> granularity ;
988- start = max (ALIGN_DOWN (addr , size ), prange -> start );
989- last = min (ALIGN (addr + 1 , size ) - 1 , prange -> last );
946+ svm_range_lock (parent );
947+ if (prange != parent )
948+ mutex_lock_nested (& prange -> lock , 1 );
949+ r = svm_range_split_by_granularity (p , mm , addr , parent , prange );
950+ if (prange != parent )
951+ mutex_unlock (& prange -> lock );
952+ svm_range_unlock (parent );
953+ if (r ) {
954+ pr_debug ("failed %d to split range by granularity\n" , r );
955+ goto out_unlock_prange ;
956+ }
990957
991- r = svm_migrate_vram_to_ram (prange , vmf -> vma -> vm_mm , start , last ,
992- KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU , vmf -> page );
958+ r = svm_migrate_vram_to_ram (prange , vmf -> vma -> vm_mm ,
959+ KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU ,
960+ vmf -> page );
993961 if (r )
994962 pr_debug ("failed %d migrate svms 0x%p range 0x%p [0x%lx 0x%lx]\n" ,
995- r , prange -> svms , prange , start , last );
963+ r , prange -> svms , prange , prange -> start , prange -> last );
964+
965+ /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */
966+ if (p -> xnack_enabled && parent == prange )
967+ op = SVM_OP_UPDATE_RANGE_NOTIFIER_AND_MAP ;
968+ else
969+ op = SVM_OP_UPDATE_RANGE_NOTIFIER ;
970+ svm_range_add_list_work (& p -> svms , parent , mm , op );
971+ schedule_deferred_list_work (& p -> svms );
996972
997973out_unlock_prange :
998- mutex_unlock (& prange -> migrate_mutex );
974+ if (prange != parent )
975+ mutex_unlock (& prange -> migrate_mutex );
976+ mutex_unlock (& parent -> migrate_mutex );
999977out_unlock_svms :
1000978 mutex_unlock (& p -> svms .lock );
1001979out_unref_process :
0 commit comments