Wrap the bare dev_pagemap inside a new struct amdgpu_pagemap that adds drm_pagemap state (dpagemap, adev back-pointer, hpa_base, initialized flag) needed by the DRM GPUSVM migration path.
Signed-off-by: Junhua Shen <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 42 ++++++++++++++++++++-- drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 6 ++-- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 2 +- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index cdbab7f8cee8..844f622f55b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -38,6 +38,8 @@ #include "amdgpu_vm.h" #include "amdgpu_xcp.h" #include "kfd_topology.h" +#include <drm/drm_pagemap.h> + extern uint64_t amdgpu_amdkfd_total_mem_size; enum TLB_FLUSH_TYPE { @@ -101,6 +103,29 @@ struct amdgpu_amdkfd_fence { uint16_t context_id; }; +/** + * struct amdgpu_pagemap - VRAM migration infrastructure for drm_pagemap + * + * Wraps struct dev_pagemap with the additional drm_pagemap state needed + * by the DRM GPUSVM migration path. Used in place of bare + * dev_pagemap when CONFIG_DRM_AMDGPU_SVM is enabled. + * + * @dpagemap: drm_pagemap wrapper providing device_map / populate_mm callbacks + * @adev: back-pointer to the owning amdgpu_device for fast lookup from + * ZONE_DEVICE pages (avoids traversing dpagemap->drm->drm_to_adev) + * @hpa_base: HPA base of the ZONE_DEVICE region (== pgmap.range.start) + * @initialized: true after successful devm_memremap_pages + dpagemap init + * @pgmap: ZONE_DEVICE registration — must be last, contains flexible-array member + */ +struct amdgpu_pagemap { + struct drm_pagemap dpagemap; + struct amdgpu_device *adev; + resource_size_t hpa_base; + bool initialized; + /* Must be last -- struct dev_pagemap ends in a flexible-array member */ + struct dev_pagemap pgmap; +}; + struct amdgpu_kfd_dev { struct kfd_dev *dev; int64_t vram_used[MAX_XCP]; @@ -111,12 +136,23 @@ struct amdgpu_kfd_dev { /* Client for KFD BO GEM handle allocations */ struct drm_client_dev client; - /* HMM page migration MEMORY_DEVICE_PRIVATE mapping - * Must be last --ends in a flexible-array member. - */ + /* HMM page migration MEMORY_DEVICE_PRIVATE mapping. */ +#if IS_ENABLED(CONFIG_DRM_AMDGPU_SVM) + struct amdgpu_pagemap apagemap; +#else struct dev_pagemap pgmap; +#endif }; +/** + * amdgpu_kfd_pgmap - Get the dev_pagemap for HMM page migration + */ +#if IS_ENABLED(CONFIG_DRM_AMDGPU_SVM) +#define amdgpu_kfd_pgmap(adev) (&(adev)->kfd.apagemap.pgmap) +#else +#define amdgpu_kfd_pgmap(adev) (&(adev)->kfd.pgmap) +#endif + enum kgd_engine_type { KGD_ENGINE_PFP = 1, KGD_ENGINE_ME, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c index 10bc81ce37cb..289683cabd79 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -212,7 +212,7 @@ svm_migrate_copy_done(struct amdgpu_device *adev, struct dma_fence *mfence) unsigned long svm_migrate_addr_to_pfn(struct amdgpu_device *adev, unsigned long addr) { - return (addr + adev->kfd.pgmap.range.start) >> PAGE_SHIFT; + return (addr + amdgpu_kfd_pgmap(adev)->range.start) >> PAGE_SHIFT; } static void @@ -242,7 +242,7 @@ svm_migrate_addr(struct amdgpu_device *adev, struct page *page) unsigned long addr; addr = page_to_pfn(page) << PAGE_SHIFT; - return (addr - adev->kfd.pgmap.range.start); + return (addr - amdgpu_kfd_pgmap(adev)->range.start); } static struct page * @@ -1037,7 +1037,7 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev) if (adev->apu_prefer_gtt) return 0; - pgmap = &kfddev->pgmap; + pgmap = amdgpu_kfd_pgmap(adev); memset(pgmap, 0, sizeof(*pgmap)); /* TODO: register all vram to HMM for now. diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 9b4143328371..4c11ed4e8ea3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -185,7 +185,7 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, addr[i] = (hmm_pfns[i] << PAGE_SHIFT) + bo_adev->vm_manager.vram_base_offset - - bo_adev->kfd.pgmap.range.start; + amdgpu_kfd_pgmap(bo_adev)->range.start; addr[i] |= SVM_RANGE_VRAM_DOMAIN; pr_debug_ratelimited("vram address: 0x%llx\n", addr[i]); continue; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h index a63dfc95b602..8059169c7e0d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h @@ -200,7 +200,7 @@ void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_s /* SVM API and HMM page migration work together, device memory type * is initialized to not 0 when page migration register device memory. */ -#define KFD_IS_SVM_API_SUPPORTED(adev) ((adev)->kfd.pgmap.type != 0 ||\ +#define KFD_IS_SVM_API_SUPPORTED(adev) (amdgpu_kfd_pgmap(adev)->type != 0 ||\ ((adev)->apu_prefer_gtt)) void svm_range_bo_unref_async(struct svm_range_bo *svm_bo); -- 2.34.1
