diff options
author | Felix Kuehling <Felix.Kuehling@amd.com> | 2018-02-06 20:32:37 -0500 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2018-02-06 20:32:37 -0500 |
commit | 3c728d3aa1fd5c7c2461835a93ac8fad57813db6 (patch) | |
tree | cecd89fba4db2b7cab21b4b0d7ee00d38a6484e9 /drivers/gpu/drm/amd | |
parent | 155494dbbbf4d6d6512b8bc2dc6bc483e47e1c71 (diff) |
drm/amdgpu: add amdgpu_sync_clone
Cloning a sync object is useful for waiting for a sync object
without locking the original structure indefinitely, blocking
other threads.
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h | 1 |
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index b8d3b87fd43e..2d6f5ec77a68 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
@@ -322,6 +322,41 @@ struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit | |||
322 | return NULL; | 322 | return NULL; |
323 | } | 323 | } |
324 | 324 | ||
325 | /** | ||
326 | * amdgpu_sync_clone - clone a sync object | ||
327 | * | ||
328 | * @source: sync object to clone | ||
329 | * @clone: pointer to destination sync object | ||
330 | * | ||
331 | * Adds references to all unsignaled fences in @source to @clone. Also | ||
332 | * removes signaled fences from @source while at it. | ||
333 | */ | ||
334 | int amdgpu_sync_clone(struct amdgpu_sync *source, struct amdgpu_sync *clone) | ||
335 | { | ||
336 | struct amdgpu_sync_entry *e; | ||
337 | struct hlist_node *tmp; | ||
338 | struct dma_fence *f; | ||
339 | int i, r; | ||
340 | |||
341 | hash_for_each_safe(source->fences, i, tmp, e, node) { | ||
342 | f = e->fence; | ||
343 | if (!dma_fence_is_signaled(f)) { | ||
344 | r = amdgpu_sync_fence(NULL, clone, f, e->explicit); | ||
345 | if (r) | ||
346 | return r; | ||
347 | } else { | ||
348 | hash_del(&e->node); | ||
349 | dma_fence_put(f); | ||
350 | kmem_cache_free(amdgpu_sync_slab, e); | ||
351 | } | ||
352 | } | ||
353 | |||
354 | dma_fence_put(clone->last_vm_update); | ||
355 | clone->last_vm_update = dma_fence_get(source->last_vm_update); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
325 | int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr) | 360 | int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr) |
326 | { | 361 | { |
327 | struct amdgpu_sync_entry *e; | 362 | struct amdgpu_sync_entry *e; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h index 7aba38d5c9df..10cf23a57f17 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h | |||
@@ -50,6 +50,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
50 | struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, | 50 | struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, |
51 | struct amdgpu_ring *ring); | 51 | struct amdgpu_ring *ring); |
52 | struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit); | 52 | struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit); |
53 | int amdgpu_sync_clone(struct amdgpu_sync *source, struct amdgpu_sync *clone); | ||
53 | int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr); | 54 | int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr); |
54 | void amdgpu_sync_free(struct amdgpu_sync *sync); | 55 | void amdgpu_sync_free(struct amdgpu_sync *sync); |
55 | int amdgpu_sync_init(void); | 56 | int amdgpu_sync_init(void); |