Commit c969c5fd authored by Philip Yang's avatar Philip Yang Committed by Alex Deucher

drm/amdkfd: Remove prefault before migrating to VRAM

Prefaulting potentially allocates system memory pages before a
migration. This adds unnecessary overhead. Instead we can skip
unallocated pages in the migration and just point migrate->dst to a
0-initialized VRAM page directly. Then the VRAM page will be inserted
to the PTE. A subsequent CPU page fault will migrate the page back to
system memory.
Signed-off-by: default avatarPhilip Yang <Philip.Yang@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e1f84eef
...@@ -322,12 +322,13 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, ...@@ -322,12 +322,13 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
for (i = j = 0; i < npages; i++) { for (i = j = 0; i < npages; i++) {
struct page *spage; struct page *spage;
dst[i] = cursor.start + (j << PAGE_SHIFT);
migrate->dst[i] = svm_migrate_addr_to_pfn(adev, dst[i]);
svm_migrate_get_vram_page(prange, migrate->dst[i]);
migrate->dst[i] = migrate_pfn(migrate->dst[i]);
spage = migrate_pfn_to_page(migrate->src[i]); spage = migrate_pfn_to_page(migrate->src[i]);
if (spage && !is_zone_device_page(spage)) { if (spage && !is_zone_device_page(spage)) {
dst[i] = cursor.start + (j << PAGE_SHIFT);
migrate->dst[i] = svm_migrate_addr_to_pfn(adev, dst[i]);
svm_migrate_get_vram_page(prange, migrate->dst[i]);
migrate->dst[i] = migrate_pfn(migrate->dst[i]);
src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE, src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE,
DMA_TO_DEVICE); DMA_TO_DEVICE);
r = dma_mapping_error(dev, src[i]); r = dma_mapping_error(dev, src[i]);
...@@ -522,9 +523,6 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc, ...@@ -522,9 +523,6 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
pr_debug("svms 0x%p [0x%lx 0x%lx] to gpu 0x%x\n", prange->svms, pr_debug("svms 0x%p [0x%lx 0x%lx] to gpu 0x%x\n", prange->svms,
prange->start, prange->last, best_loc); prange->start, prange->last, best_loc);
/* FIXME: workaround for page locking bug with invalid pages */
svm_range_prefault(prange, mm, SVM_ADEV_PGMAP_OWNER(adev));
start = prange->start << PAGE_SHIFT; start = prange->start << PAGE_SHIFT;
end = (prange->last + 1) << PAGE_SHIFT; end = (prange->last + 1) << PAGE_SHIFT;
......
...@@ -3181,28 +3181,6 @@ svm_range_best_prefetch_location(struct svm_range *prange) ...@@ -3181,28 +3181,6 @@ svm_range_best_prefetch_location(struct svm_range *prange)
return best_loc; return best_loc;
} }
/* FIXME: This is a workaround for page locking bug when some pages are
* invalid during migration to VRAM
*/
void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm,
void *owner)
{
struct hmm_range *hmm_range;
int r;
if (prange->validated_once)
return;
r = amdgpu_hmm_range_get_pages(&prange->notifier, mm, NULL,
prange->start << PAGE_SHIFT,
prange->npages, &hmm_range,
false, true, owner);
if (!r) {
amdgpu_hmm_range_get_pages_done(hmm_range);
prange->validated_once = true;
}
}
/* svm_range_trigger_migration - start page migration if prefetch loc changed /* svm_range_trigger_migration - start page migration if prefetch loc changed
* @mm: current process mm_struct * @mm: current process mm_struct
* @prange: svm range structure * @prange: svm range structure
......
...@@ -181,8 +181,6 @@ void schedule_deferred_list_work(struct svm_range_list *svms); ...@@ -181,8 +181,6 @@ void schedule_deferred_list_work(struct svm_range_list *svms);
void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr, void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr,
unsigned long offset, unsigned long npages); unsigned long offset, unsigned long npages);
void svm_range_free_dma_mappings(struct svm_range *prange); void svm_range_free_dma_mappings(struct svm_range *prange);
void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm,
void *owner);
int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges, int svm_range_get_info(struct kfd_process *p, uint32_t *num_svm_ranges,
uint64_t *svm_priv_data_size); uint64_t *svm_priv_data_size);
int kfd_criu_checkpoint_svm(struct kfd_process *p, int kfd_criu_checkpoint_svm(struct kfd_process *p,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment