Commit e49fe404 authored by Felix Kuehling's avatar Felix Kuehling Committed by Alex Deucher

drm/amdkfd: validate vram svm range from TTM

If svm range perfetch location is not zero, use TTM to alloc
amdgpu_bo vram nodes to validate svm range, then map vram nodes to GPUs.

Use offset to sub allocate from the same amdgpu_bo to handle overlap
vram range while adding new range or unmapping range.

svm_bo has ref count to trace the shared ranges. If all ranges of shared
amdgpu_bo are migrated to ram, ref count becomes 0, then amdgpu_bo is
released, all ranges svm_bo is set to NULL.

To migrate range from ram back to vram, allocate the same amdgpu_bo
with previous offset if the range has svm_bo.

If prange migrate to VRAM, no CPU mapping exist, then process exit will
not have unmap callback for this prange to free prange and svm bo. Free
outstanding pranges from svms list before process is freed in
svm_range_list_fini.
Signed-off-by: default avatarPhilip Yang <Philip.Yang@amd.com>
Signed-off-by: default avatarAlex Sierra <alex.sierra@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c46ebb6a
This diff is collapsed.
...@@ -33,6 +33,13 @@ ...@@ -33,6 +33,13 @@
#include "amdgpu.h" #include "amdgpu.h"
#include "kfd_priv.h" #include "kfd_priv.h"
struct svm_range_bo {
struct amdgpu_bo *bo;
struct kref kref;
struct list_head range_list; /* all svm ranges shared this bo */
spinlock_t list_lock;
};
enum svm_work_list_ops { enum svm_work_list_ops {
SVM_OP_NULL, SVM_OP_NULL,
SVM_OP_UNMAP_RANGE, SVM_OP_UNMAP_RANGE,
...@@ -60,6 +67,10 @@ struct svm_work_list_item { ...@@ -60,6 +67,10 @@ struct svm_work_list_item {
* @mapping: bo_va mapping structure to create and update GPU page table * @mapping: bo_va mapping structure to create and update GPU page table
* @npages: number of pages * @npages: number of pages
* @dma_addr: dma mapping address on each GPU for system memory physical page * @dma_addr: dma mapping address on each GPU for system memory physical page
* @ttm_res: vram ttm resource map
* @offset: range start offset within mm_nodes
* @svm_bo: struct to manage splited amdgpu_bo
* @svm_bo_list:link list node, to scan all ranges which share same svm_bo
* @lock: protect prange start, last, child_list, svm_bo_list * @lock: protect prange start, last, child_list, svm_bo_list
* @saved_flags:save/restore current PF_MEMALLOC flags * @saved_flags:save/restore current PF_MEMALLOC flags
* @flags: flags defined as KFD_IOCTL_SVM_FLAG_* * @flags: flags defined as KFD_IOCTL_SVM_FLAG_*
...@@ -91,6 +102,10 @@ struct svm_range { ...@@ -91,6 +102,10 @@ struct svm_range {
struct amdgpu_bo_va_mapping mapping; struct amdgpu_bo_va_mapping mapping;
uint64_t npages; uint64_t npages;
dma_addr_t *dma_addr[MAX_GPU_INSTANCE]; dma_addr_t *dma_addr[MAX_GPU_INSTANCE];
struct ttm_resource *ttm_res;
uint64_t offset;
struct svm_range_bo *svm_bo;
struct list_head svm_bo_list;
struct mutex lock; struct mutex lock;
unsigned int saved_flags; unsigned int saved_flags;
uint32_t flags; uint32_t flags;
...@@ -124,5 +139,10 @@ void svm_range_list_fini(struct kfd_process *p); ...@@ -124,5 +139,10 @@ void svm_range_list_fini(struct kfd_process *p);
int svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start, int svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
uint64_t size, uint32_t nattrs, uint64_t size, uint32_t nattrs,
struct kfd_ioctl_svm_attribute *attrs); struct kfd_ioctl_svm_attribute *attrs);
struct amdgpu_device *svm_range_get_adev_by_id(struct svm_range *prange,
uint32_t id);
int svm_range_vram_node_new(struct amdgpu_device *adev,
struct svm_range *prange, bool clear);
void svm_range_vram_node_free(struct svm_range *prange);
#endif /* KFD_SVM_H_ */ #endif /* KFD_SVM_H_ */
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