drm/amdkfd: Release an acquired process vm
authorOak Zeng <Oak.Zeng@amd.com>
Mon, 27 Aug 2018 19:18:36 +0000 (15:18 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 29 Aug 2018 17:35:00 +0000 (12:35 -0500)
For compute vm acquired from amdgpu, vm.pasid is managed
by kfd. Decouple pasid from such vm on process destroy
to avoid duplicate pasid release.

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>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/include/kgd_kfd_interface.h

index ba0057e94d5eccee0416de2f4f99da9f9e17f7b1..2a1da3fe2b06942be68b0d2bf585b36c7f3aa59f 100644 (file)
@@ -172,6 +172,7 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
 void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
                                struct amdgpu_vm *vm);
 void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm);
+void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm);
 uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm);
 int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
                struct kgd_dev *kgd, uint64_t va, uint64_t size,
index ea3f698aef5eaec1353492b636c81eb2d2f84b78..6f0b5267addba3d47614ee5b9f57bb81788403c3 100644 (file)
@@ -205,6 +205,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm,
        .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm,
        .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm,
+       .release_process_vm = amdgpu_amdkfd_gpuvm_release_process_vm,
        .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir,
        .set_vm_context_page_table_base = set_vm_context_page_table_base,
        .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu,
index f6e53e9352bd83c23f6cfe1d230839a07c17dc20..ea7c18ce7754720bd97cf1ad3e6ba9f00a2e6279 100644 (file)
@@ -164,6 +164,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm,
        .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm,
        .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm,
+       .release_process_vm = amdgpu_amdkfd_gpuvm_release_process_vm,
        .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir,
        .set_vm_context_page_table_base = set_vm_context_page_table_base,
        .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu,
index 8efedfcb9dfca50defdeec3a189968f3f425a287..3dc987cab0eab97396a536eb6a32f8f574855721 100644 (file)
@@ -201,6 +201,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm,
        .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm,
        .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm,
+       .release_process_vm = amdgpu_amdkfd_gpuvm_release_process_vm,
        .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir,
        .set_vm_context_page_table_base = set_vm_context_page_table_base,
        .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu,
index 1cbdd9a7538eae8d5617d0e867d34ce4a92d2eff..e7ceae05d51790ce7c2b114f721ec30b15c520a5 100644 (file)
@@ -1114,6 +1114,25 @@ void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm)
        kfree(vm);
 }
 
+void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm)
+{
+       struct amdgpu_device *adev = get_amdgpu_device(kgd);
+        struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
+
+       if (WARN_ON(!kgd || !vm))
+                return;
+
+        pr_debug("Releasing process vm %p\n", vm);
+
+        /* The original pasid of amdgpu vm has already been
+         * released during making a amdgpu vm to a compute vm
+         * The current pasid is managed by kfd and will be
+         * released on kfd process destroy. Set amdgpu pasid
+         * to 0 to avoid duplicate release.
+         */
+       amdgpu_vm_release_compute(adev, avm);
+}
+
 uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm)
 {
        struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
index 272b7902a25c704f7a6543bfe721d0c855cdc1a8..23c78af850c61a7f5a62830e8824aff18e102239 100644 (file)
@@ -2823,6 +2823,26 @@ unreserve_bo:
        return r;
 }
 
+/**
+ * amdgpu_vm_release_compute - release a compute vm
+ * @adev: amdgpu_device pointer
+ * @vm: a vm turned into compute vm by calling amdgpu_vm_make_compute
+ *
+ * This is a correspondant of amdgpu_vm_make_compute. It decouples compute
+ * pasid from vm. Compute should stop use of vm after this call.
+ */
+void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+{
+       if (vm->pasid) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags);
+               idr_remove(&adev->vm_manager.pasid_idr, vm->pasid);
+               spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags);
+       }
+       vm->pasid = 0;
+}
+
 /**
  * amdgpu_vm_free_levels - free PD/PT levels
  *
index 24b02c91ce0cef468807cff5c1f671041d7bc916..62116fa44718917448dbdd37031f10005106afcf 100644 (file)
@@ -298,6 +298,7 @@ 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, unsigned int pasid);
+void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
 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);
index a246b8d76c868c34044f6166724b2487c127fee4..0039e451d9af2a7e816dafb64559595b22a3d8a4 100644 (file)
@@ -322,8 +322,10 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
                pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
                                pdd->dev->id, p->pasid);
 
-               if (pdd->drm_file)
+               if (pdd->drm_file) {
+                       pdd->dev->kfd2kgd->release_process_vm(pdd->dev->kgd, pdd->vm);
                        fput(pdd->drm_file);
+               }
                else if (pdd->vm)
                        pdd->dev->kfd2kgd->destroy_process_vm(
                                pdd->dev->kgd, pdd->vm);
index 4b9981351bb3d2a3c66e078a3eea11cbdf8d9e47..814576f6ca1c36e771f434204e8c33d7d980ad1b 100644 (file)
@@ -378,6 +378,7 @@ struct kfd2kgd_calls {
                        unsigned int pasid, void **vm, void **process_info,
                        struct dma_fence **ef);
        void (*destroy_process_vm)(struct kgd_dev *kgd, void *vm);
+       void (*release_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,
                        uint32_t vmid, uint32_t page_table_base);