We need the device alive and kicking for the move notify callback to work correctly. Not sure if we should have that here or in the callback itself, but go with the defensive variant for now. Signed-off-by: Christian König <christian.koenig@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 37 ++++++++++++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 4 +-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index a9475b207510..8756f505c87d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -512,6 +512,7 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, { struct dma_buf_attachment *attach; struct drm_gem_object *obj; + int r; if (dma_buf->ops == &amdgpu_dmabuf_ops) { obj = dma_buf->priv; @@ -525,20 +526,48 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, } } + r = pm_runtime_resume_and_get(dev->dev); + if (r) + return ERR_PTR(r); + obj = amdgpu_dma_buf_create_obj(dev, dma_buf); - if (IS_ERR(obj)) - return obj; + if (IS_ERR(obj)) { + r = PTR_ERR(obj); + goto err_pm; + } attach = dma_buf_dynamic_attach(dma_buf, dev->dev, &amdgpu_dma_buf_attach_ops, obj); if (IS_ERR(attach)) { - drm_gem_object_put(obj); - return ERR_CAST(attach); + r = PTR_ERR(attach); + goto err_put; } get_dma_buf(dma_buf); obj->import_attach = attach; return obj; + +err_put: + drm_gem_object_put(obj); + +err_pm: + pm_runtime_put_autosuspend(dev->dev); + return ERR_PTR(r); +} + +/** + * amdgpu_gem_prime_destroy - destroy an imported BO again + * @bo: the imported BO + * + * Make sure to cleanup the SG table, detach from the DMA-buf and drop the PM + * reference we grabbed. + */ +void amdgpu_gem_prime_destroy(struct amdgpu_bo *bo) +{ + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + + drm_prime_gem_destroy(&bo->tbo.base, bo->tbo.sg); + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h index 3e93b9b407a9..14cc6a873444 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.h @@ -29,6 +29,7 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_gem_object *gobj, int flags); struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); +void amdgpu_gem_prime_destroy(struct amdgpu_bo *bo); bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev, struct amdgpu_bo *bo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index ff9dc377a3a0..6a22eaf38056 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -39,6 +39,7 @@ #include "amdgpu.h" #include "amdgpu_trace.h" #include "amdgpu_amdkfd.h" +#include "amdgpu_dma_buf.h" /** * DOC: amdgpu_object @@ -58,9 +59,8 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo) struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); amdgpu_bo_kunmap(bo); - if (bo->tbo.base.import_attach) - drm_prime_gem_destroy(&bo->tbo.base, bo->tbo.sg); + amdgpu_gem_prime_destroy(bo); drm_gem_object_release(&bo->tbo.base); amdgpu_bo_unref(&bo->parent); kvfree(bo); -- 2.25.1