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; + return drm_gem_prime_export(dev, gobj, flags); }
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); }
On 11/05/2016 01:06 PM, Christian König wrote:
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.
Ok. I'll place the code before the actual pinning code in that function then, so it can error out early if needed.
-mario
Apart from that this looks really good to me.
Regards, Christian.
return drm_gem_prime_export(dev, gobj, flags);
}
dri-devel@lists.freedesktop.org