Skip to content

Commit 541c341

Browse files
amd-yangpalexdeucher
authored andcommitted
Revert "drm/amdkfd: Use partial migrations in GPU page faults"
This reverts commit dc427a4. The change prevents migrating the entire range to VRAM because retry fault restore_pages map the remaining system memory range to GPUs. It will work correctly to submit together with partial mapping to GPU patch later. Signed-off-by: Philip Yang <Philip.Yang@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent afaec20 commit 541c341

4 files changed

Lines changed: 85 additions & 160 deletions

File tree

drivers/gpu/drm/amd/amdkfd/kfd_migrate.c

Lines changed: 64 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
492490
static int
493491
svm_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
*/
682670
static long
683671
svm_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);
765752
out:
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
*/
790773
int 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
*/
881844
static int
882845
svm_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

908869
int
909870
svm_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
*/
933890
static 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

997973
out_unlock_prange:
998-
mutex_unlock(&prange->migrate_mutex);
974+
if (prange != parent)
975+
mutex_unlock(&prange->migrate_mutex);
976+
mutex_unlock(&parent->migrate_mutex);
999977
out_unlock_svms:
1000978
mutex_unlock(&p->svms.lock);
1001979
out_unref_process:

drivers/gpu/drm/amd/amdkfd/kfd_migrate.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,9 @@ enum MIGRATION_COPY_DIR {
4141
};
4242

4343
int svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
44-
unsigned long start, unsigned long last,
4544
struct mm_struct *mm, uint32_t trigger);
46-
4745
int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
48-
unsigned long start, unsigned long last,
49-
uint32_t trigger, struct page *fault_page);
50-
46+
uint32_t trigger, struct page *fault_page);
5147
unsigned long
5248
svm_migrate_addr_to_pfn(struct amdgpu_device *adev, unsigned long addr);
5349

0 commit comments

Comments
 (0)