From ea3b40b3035c304dc2121b76fdc6b3c2f9d4c9ba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Aug 2016 15:40:41 +0100 Subject: [PATCH] drm/amdgpu, drm/radeon, drm/nouveau: Export fences to third parties via dma-buf All three drivers manage their own fence objects on a ttm reservation to handle internal scheduling. Add that fence to the dma-buf reservation object as well, so third parties can also schedule using the shared bo in a completely hackish fashion. --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 11 +++++++++++ drivers/gpu/drm/drm_gem.c | 15 +++++++++++++++ drivers/gpu/drm/nouveau/nouveau_bo.c | 10 ++++++++++ drivers/gpu/drm/radeon/radeon_object.c | 11 +++++++++++ include/drm/drm_gem.h | 2 ++ 5 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 6f0873c75a25..a4c711d0851c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -673,4 +673,15 @@ void amdgpu_bo_fence(struct amdgpu_bo *bo, struct fence *fence, reservation_object_add_shared_fence(resv, fence); else reservation_object_add_excl_fence(resv, fence); + + resv = drm_gem_object_get_resv(&bo->gem_base); + if (resv) { + /* XXX deadlock with caller? */ + ww_mutex_lock(&resv->lock, NULL); + if (shared) + reservation_object_add_shared_fence(resv, fence); + else + reservation_object_add_excl_fence(resv, fence); + ww_mutex_unlock(&resv->lock); + } } diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 9134ae134667..c3f9c3d07d3e 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1004,3 +1004,18 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) return ret; } EXPORT_SYMBOL(drm_gem_mmap); + +struct reservation_object *drm_gem_object_get_resv(struct drm_gem_object *obj) +{ + struct dma_buf *dma_buf; + + if (obj->dma_buf) + dma_buf = obj->dma_buf; + else if (obj->import_attach) + dma_buf = obj->import_attach->dmabuf; + else + return NULL; + + return dma_buf->resv; +} +EXPORT_SYMBOL(drm_gem_object_get_resv); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 528bdeffb339..73d586ec08ec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1551,6 +1551,16 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence, bool excl reservation_object_add_excl_fence(resv, &fence->base); else if (fence) reservation_object_add_shared_fence(resv, &fence->base); + + resv = drm_gem_object_get_resv(&nvbo->gem); + if (resv) { + ww_mutex_lock(&resv->lock, NULL); + if (exclusive) + reservation_object_add_excl_fence(resv, &fence->base); + else if (fence) + reservation_object_add_shared_fence(resv, &fence->base); + ww_mutex_unlock(&resv->lock); + } } struct ttm_bo_driver nouveau_bo_driver = { diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index be30861afae9..294c10988c15 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -860,4 +860,15 @@ void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, reservation_object_add_shared_fence(resv, &fence->base); else reservation_object_add_excl_fence(resv, &fence->base); + + resv = drm_gem_object_get_resv(&bo->gem_base); + if (resv) { + /* XXX deadlock with caller? */ + ww_mutex_lock(&resv->lock, NULL); + if (shared) + reservation_object_add_shared_fence(resv, &fence->base); + else + reservation_object_add_excl_fence(resv, &fence->base); + ww_mutex_unlock(&resv->lock); + } } diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index f06f6c53f476..a5055b667eca 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -228,4 +228,6 @@ int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, uint32_t handle); +struct reservation_object *drm_gem_object_get_resv(struct drm_gem_object *obj); + #endif /* __DRM_GEM_H__ */ -- 2.8.1