drm/amdgpu: Set pasid for compute vm (v2)
To make a amdgpu vm to a compute vm, the old pasid will be freed and replaced with a pasid managed by kfd. Kfd can't reuse original pasid allocated by amdgpu because kfd uses different pasid policy with amdgpu. For example, all graphic devices share one same pasid in a process. v2: rebase (Alex) Signed-off-by: Oak Zeng <Oak.Zeng@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
bdb1922abd
commit
1685b01a85
|
@ -162,11 +162,11 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd);
|
|||
})
|
||||
|
||||
/* GPUVM API */
|
||||
int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
|
||||
void **process_info,
|
||||
int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, unsigned int pasid,
|
||||
void **vm, void **process_info,
|
||||
struct dma_fence **ef);
|
||||
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
|
||||
struct file *filp,
|
||||
struct file *filp, unsigned int pasid,
|
||||
void **vm, void **process_info,
|
||||
struct dma_fence **ef);
|
||||
void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
|
||||
|
|
|
@ -1000,8 +1000,8 @@ create_evict_fence_fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
|
||||
void **process_info,
|
||||
int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, unsigned int pasid,
|
||||
void **vm, void **process_info,
|
||||
struct dma_fence **ef)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
|
@ -1013,7 +1013,7 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
|
|||
return -ENOMEM;
|
||||
|
||||
/* Initialize AMDGPU part of the VM */
|
||||
ret = amdgpu_vm_init(adev, new_vm, AMDGPU_VM_CONTEXT_COMPUTE, 0);
|
||||
ret = amdgpu_vm_init(adev, new_vm, AMDGPU_VM_CONTEXT_COMPUTE, pasid);
|
||||
if (ret) {
|
||||
pr_err("Failed init vm ret %d\n", ret);
|
||||
goto amdgpu_vm_init_fail;
|
||||
|
@ -1036,7 +1036,7 @@ amdgpu_vm_init_fail:
|
|||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
|
||||
struct file *filp,
|
||||
struct file *filp, unsigned int pasid,
|
||||
void **vm, void **process_info,
|
||||
struct dma_fence **ef)
|
||||
{
|
||||
|
@ -1051,7 +1051,7 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
|
|||
return -EINVAL;
|
||||
|
||||
/* Convert VM into a compute VM */
|
||||
ret = amdgpu_vm_make_compute(adev, avm);
|
||||
ret = amdgpu_vm_make_compute(adev, avm, pasid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -2740,7 +2740,7 @@ error_free_sched_entity:
|
|||
* Returns:
|
||||
* 0 for success, -errno for errors.
|
||||
*/
|
||||
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
||||
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid)
|
||||
{
|
||||
bool pte_support_ats = (adev->asic_type == CHIP_RAVEN);
|
||||
int r;
|
||||
|
@ -2752,7 +2752,20 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
/* Sanity checks */
|
||||
if (!RB_EMPTY_ROOT(&vm->va.rb_root) || vm->root.entries) {
|
||||
r = -EINVAL;
|
||||
goto error;
|
||||
goto unreserve_bo;
|
||||
}
|
||||
|
||||
if (pasid) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
|
||||
r = idr_alloc(&adev->vm_manager.pasid_idr, vm, pasid, pasid + 1,
|
||||
GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
|
||||
|
||||
if (r == -ENOSPC)
|
||||
goto unreserve_bo;
|
||||
r = 0;
|
||||
}
|
||||
|
||||
/* Check if PD needs to be reinitialized and do it before
|
||||
|
@ -2763,7 +2776,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
adev->vm_manager.root_level,
|
||||
pte_support_ats);
|
||||
if (r)
|
||||
goto error;
|
||||
goto free_idr;
|
||||
}
|
||||
|
||||
/* Update VM state */
|
||||
|
@ -2782,13 +2795,30 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
idr_remove(&adev->vm_manager.pasid_idr, vm->pasid);
|
||||
spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
|
||||
|
||||
/* Free the original amdgpu allocated pasid
|
||||
* Will be replaced with kfd allocated pasid
|
||||
*/
|
||||
amdgpu_pasid_free(vm->pasid);
|
||||
vm->pasid = 0;
|
||||
}
|
||||
|
||||
/* Free the shadow bo for compute VM */
|
||||
amdgpu_bo_unref(&vm->root.base.bo->shadow);
|
||||
|
||||
error:
|
||||
if (pasid)
|
||||
vm->pasid = pasid;
|
||||
|
||||
goto unreserve_bo;
|
||||
|
||||
free_idr:
|
||||
if (pasid) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
|
||||
idr_remove(&adev->vm_manager.pasid_idr, pasid);
|
||||
spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
|
||||
}
|
||||
unreserve_bo:
|
||||
amdgpu_bo_unreserve(vm->root.base.bo);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -297,7 +297,7 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev);
|
|||
void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int vm_context, unsigned int pasid);
|
||||
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);
|
||||
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||
bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
|
||||
unsigned int pasid);
|
||||
|
|
|
@ -687,11 +687,11 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
|
|||
|
||||
if (drm_file)
|
||||
ret = dev->kfd2kgd->acquire_process_vm(
|
||||
dev->kgd, drm_file,
|
||||
dev->kgd, drm_file, p->pasid,
|
||||
&pdd->vm, &p->kgd_process_info, &p->ef);
|
||||
else
|
||||
ret = dev->kfd2kgd->create_process_vm(
|
||||
dev->kgd, &pdd->vm, &p->kgd_process_info, &p->ef);
|
||||
dev->kgd, p->pasid, &pdd->vm, &p->kgd_process_info, &p->ef);
|
||||
if (ret) {
|
||||
pr_err("Failed to create process VM object\n");
|
||||
return ret;
|
||||
|
|
|
@ -372,10 +372,11 @@ struct kfd2kgd_calls {
|
|||
struct kfd_cu_info *cu_info);
|
||||
uint64_t (*get_vram_usage)(struct kgd_dev *kgd);
|
||||
|
||||
int (*create_process_vm)(struct kgd_dev *kgd, void **vm,
|
||||
int (*create_process_vm)(struct kgd_dev *kgd, unsigned int pasid, void **vm,
|
||||
void **process_info, struct dma_fence **ef);
|
||||
int (*acquire_process_vm)(struct kgd_dev *kgd, struct file *filp,
|
||||
void **vm, void **process_info, struct dma_fence **ef);
|
||||
unsigned int pasid, void **vm, void **process_info,
|
||||
struct dma_fence **ef);
|
||||
void (*destroy_process_vm)(struct kgd_dev *kgd, void *vm);
|
||||
uint32_t (*get_process_page_dir)(void *vm);
|
||||
void (*set_vm_context_page_table_base)(struct kgd_dev *kgd,
|
||||
|
|
Loading…
Reference in New Issue