Am 05.11.2016 um 01:56 schrieb Mario Kleiner:
External clients which import our bo's wait only for exclusive dmabuf-fences, not on shared ones, so attach fences on such exported buffers as exclusive ones.
See discussion in thread: https://lists.freedesktop.org/archives/dri-devel/2016-October/122370.html
Tested on Intel iGPU + AMD Tonga dGPU as DRI3/Present Prime render offload, and with the Tonga standalone as primary gpu.
v2: Add a wait for all shared fences before prime export, as suggested by Christian Koenig.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95472 (v1) Tested-by: Mike Lothian mike@fireburn.co.uk Signed-off-by: Mario Kleiner mario.kleiner.de@gmail.com Cc: Christian König christian.koenig@amd.com Cc: Michel Dänzer michel.daenzer@amd.com
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 039b57e..a337d56 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -459,6 +459,7 @@ struct amdgpu_bo { u64 metadata_flags; void *metadata; u32 metadata_size;
- bool prime_exported; /* list of all virtual address to which this bo
*/
- is associated to
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 651115d..51c6f60 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, entry->priority = min(info[i].bo_priority, AMDGPU_BO_LIST_MAX_PRIORITY); entry->tv.bo = &entry->robj->tbo;
entry->tv.shared = true;
entry->tv.shared = !entry->robj->prime_exported;
if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS) gds_obj = entry->robj;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 7700dc2..0ed92a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -117,9 +117,20 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev, int flags) { struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
long ret;
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) return ERR_PTR(-EPERM);
/*
* Wait for all shared fences to complete before we switch to future
* use of exclusive fence on this prime_exported bo.
*/
ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false,
MAX_SCHEDULE_TIMEOUT);
WARN(ret <= 0, "Fence wait returns %li\n", ret);
bo->prime_exported = true;
As Michel noted as well this is the wrong function for this, cause this is used for buffer sharing without DMA-buf as well. Try to put it into amdgpu_gem_prime_pin() instead.
I would also improve the error handling so that we return the error when the wait failed.
Apart from that this looks really good to me.
Regards, Christian.
return drm_gem_prime_export(dev, gobj, flags); }