Commit 5702d052 authored by Felix Kuehling's avatar Felix Kuehling Committed by Alex Deucher

drm/amdgpu: Fix dangling kfd_bo pointer for shared BOs

If a kfd_bo was shared (e.g. a dmabuf export), the original kfd_bo may be
freed when the amdgpu_bo still lives on. Free the kfd_bo struct in the
release_notify callback then the amdgpu_bo is freed.
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Reviewed-By: default avatarRamesh Errabolu <Ramesh.Errabolu@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b8c20c74
...@@ -297,7 +297,7 @@ void amdgpu_amdkfd_ras_poison_consumption_handler(struct kgd_dev *kgd); ...@@ -297,7 +297,7 @@ void amdgpu_amdkfd_ras_poison_consumption_handler(struct kgd_dev *kgd);
void amdgpu_amdkfd_gpuvm_init_mem_limits(void); void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev, void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
struct amdgpu_vm *vm); struct amdgpu_vm *vm);
void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo); void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo);
void amdgpu_amdkfd_reserve_system_mem(uint64_t size); void amdgpu_amdkfd_reserve_system_mem(uint64_t size);
#else #else
static inline static inline
...@@ -312,7 +312,7 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev, ...@@ -312,7 +312,7 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
} }
static inline static inline
void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo) void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
{ {
} }
#endif #endif
......
...@@ -207,7 +207,7 @@ static void unreserve_mem_limit(struct amdgpu_device *adev, ...@@ -207,7 +207,7 @@ static void unreserve_mem_limit(struct amdgpu_device *adev,
spin_unlock(&kfd_mem_limit.mem_limit_lock); spin_unlock(&kfd_mem_limit.mem_limit_lock);
} }
void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo) void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
{ {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
u32 domain = bo->preferred_domains; u32 domain = bo->preferred_domains;
...@@ -219,6 +219,8 @@ void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo) ...@@ -219,6 +219,8 @@ void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo)
} }
unreserve_mem_limit(adev, amdgpu_bo_size(bo), domain, sg); unreserve_mem_limit(adev, amdgpu_bo_size(bo), domain, sg);
kfree(bo->kfd_bo);
} }
...@@ -1607,9 +1609,13 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( ...@@ -1607,9 +1609,13 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
drm_vma_node_revoke(&mem->bo->tbo.base.vma_node, drm_priv); drm_vma_node_revoke(&mem->bo->tbo.base.vma_node, drm_priv);
if (mem->dmabuf) if (mem->dmabuf)
dma_buf_put(mem->dmabuf); dma_buf_put(mem->dmabuf);
drm_gem_object_put(&mem->bo->tbo.base);
mutex_destroy(&mem->lock); mutex_destroy(&mem->lock);
kfree(mem);
/* If this releases the last reference, it will end up calling
* amdgpu_amdkfd_release_notify and kfree the mem struct. That's why
* this needs to be the last call here.
*/
drm_gem_object_put(&mem->bo->tbo.base);
return ret; return ret;
} }
......
...@@ -1274,7 +1274,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo) ...@@ -1274,7 +1274,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
abo = ttm_to_amdgpu_bo(bo); abo = ttm_to_amdgpu_bo(bo);
if (abo->kfd_bo) if (abo->kfd_bo)
amdgpu_amdkfd_unreserve_memory_limit(abo); amdgpu_amdkfd_release_notify(abo);
/* We only remove the fence if the resv has individualized. */ /* We only remove the fence if the resv has individualized. */
WARN_ON_ONCE(bo->type == ttm_bo_type_kernel WARN_ON_ONCE(bo->type == ttm_bo_type_kernel
......
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