Skip to content

Commit 8e94a46

Browse files
kleinermalexdeucher
authored andcommitted
drm/amdgpu: Attach exclusive fence to prime exported bo's. (v5)
External clients which import our bo's wait only for exclusive dmabuf-fences, not on shared ones, ditto for bo's which we import from external providers and write to. Therefore attach exclusive fences on prime shared buffers if our exported buffer gets imported by an external client, or if we import a buffer from an external exporter. See discussion in thread: https://lists.freedesktop.org/archives/dri-devel/2016-October/122370.html Prime export 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. v3: - Mark buffer prime_exported in amdgpu_gem_prime_pin, so we only use the exclusive fence when exporting a bo to external clients like a separate iGPU, but not when exporting/importing from/to ourselves as part of regular DRI3 fd passing. - Propagate failure of reservation_object_wait_rcu back to caller. v4: - Switch to a prime_shared_count counter instead of a flag, which gets in/decremented on prime_pin/unpin, so we can switch back to shared fences if all clients detach from our exported bo. - Also switch to exclusive fence for prime imported bo's. v5: - Drop lret, instead use int ret -> long ret, as proposed by Christian. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95472 Tested-by: Mike Lothian <mike@fireburn.co.uk> (v1) Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Reviewed-by: Christian König <christian.koenig@amd.com>. Cc: Christian König <christian.koenig@amd.com> Cc: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
1 parent e238453 commit 8e94a46

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ struct amdgpu_bo {
459459
u64 metadata_flags;
460460
void *metadata;
461461
u32 metadata_size;
462+
unsigned prime_shared_count;
462463
/* list of all virtual address to which this bo
463464
* is associated to
464465
*/

drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
132132
entry->priority = min(info[i].bo_priority,
133133
AMDGPU_BO_LIST_MAX_PRIORITY);
134134
entry->tv.bo = &entry->robj->tbo;
135-
entry->tv.shared = true;
135+
entry->tv.shared = !entry->robj->prime_shared_count;
136136

137137
if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)
138138
gds_obj = entry->robj;

drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,36 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
7474
if (ret)
7575
return ERR_PTR(ret);
7676

77+
bo->prime_shared_count = 1;
7778
return &bo->gem_base;
7879
}
7980

8081
int amdgpu_gem_prime_pin(struct drm_gem_object *obj)
8182
{
8283
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
83-
int ret = 0;
84+
long ret = 0;
8485

8586
ret = amdgpu_bo_reserve(bo, false);
8687
if (unlikely(ret != 0))
8788
return ret;
8889

90+
/*
91+
* Wait for all shared fences to complete before we switch to future
92+
* use of exclusive fence on this prime shared bo.
93+
*/
94+
ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false,
95+
MAX_SCHEDULE_TIMEOUT);
96+
if (unlikely(ret < 0)) {
97+
DRM_DEBUG_PRIME("Fence wait failed: %li\n", ret);
98+
amdgpu_bo_unreserve(bo);
99+
return ret;
100+
}
101+
89102
/* pin buffer into GTT */
90103
ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL);
104+
if (likely(ret == 0))
105+
bo->prime_shared_count++;
106+
91107
amdgpu_bo_unreserve(bo);
92108
return ret;
93109
}
@@ -102,6 +118,8 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj)
102118
return;
103119

104120
amdgpu_bo_unpin(bo);
121+
if (bo->prime_shared_count)
122+
bo->prime_shared_count--;
105123
amdgpu_bo_unreserve(bo);
106124
}
107125

0 commit comments

Comments
 (0)