OSDN Git Service

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 ba0057e..2a1da3f 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 ea3f698..6f0b526 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 f6e53e9..ea7c18c 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 8efedfc..3dc987c 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 1cbdd9a..e7ceae0 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 272b790..23c78af 100644 (file)
@@ -2824,6 +2824,26 @@ unreserve_bo:
 }
 
 /**
+ * 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
  *
  * @adev: amdgpu device structure
index 24b02c9..62116fa 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 a246b8d..0039e45 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 4b99813..814576f 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);