aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index df65c66dc956..2d6f5ec77a68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -31,6 +31,7 @@
31#include <drm/drmP.h> 31#include <drm/drmP.h>
32#include "amdgpu.h" 32#include "amdgpu.h"
33#include "amdgpu_trace.h" 33#include "amdgpu_trace.h"
34#include "amdgpu_amdkfd.h"
34 35
35struct amdgpu_sync_entry { 36struct amdgpu_sync_entry {
36 struct hlist_node node; 37 struct hlist_node node;
@@ -85,11 +86,20 @@ static bool amdgpu_sync_same_dev(struct amdgpu_device *adev,
85 */ 86 */
86static void *amdgpu_sync_get_owner(struct dma_fence *f) 87static void *amdgpu_sync_get_owner(struct dma_fence *f)
87{ 88{
88 struct drm_sched_fence *s_fence = to_drm_sched_fence(f); 89 struct drm_sched_fence *s_fence;
90 struct amdgpu_amdkfd_fence *kfd_fence;
91
92 if (!f)
93 return AMDGPU_FENCE_OWNER_UNDEFINED;
89 94
95 s_fence = to_drm_sched_fence(f);
90 if (s_fence) 96 if (s_fence)
91 return s_fence->owner; 97 return s_fence->owner;
92 98
99 kfd_fence = to_amdgpu_amdkfd_fence(f);
100 if (kfd_fence)
101 return AMDGPU_FENCE_OWNER_KFD;
102
93 return AMDGPU_FENCE_OWNER_UNDEFINED; 103 return AMDGPU_FENCE_OWNER_UNDEFINED;
94} 104}
95 105
@@ -204,11 +214,18 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
204 for (i = 0; i < flist->shared_count; ++i) { 214 for (i = 0; i < flist->shared_count; ++i) {
205 f = rcu_dereference_protected(flist->shared[i], 215 f = rcu_dereference_protected(flist->shared[i],
206 reservation_object_held(resv)); 216 reservation_object_held(resv));
217 /* We only want to trigger KFD eviction fences on
218 * evict or move jobs. Skip KFD fences otherwise.
219 */
220 fence_owner = amdgpu_sync_get_owner(f);
221 if (fence_owner == AMDGPU_FENCE_OWNER_KFD &&
222 owner != AMDGPU_FENCE_OWNER_UNDEFINED)
223 continue;
224
207 if (amdgpu_sync_same_dev(adev, f)) { 225 if (amdgpu_sync_same_dev(adev, f)) {
208 /* VM updates are only interesting 226 /* VM updates are only interesting
209 * for other VM updates and moves. 227 * for other VM updates and moves.
210 */ 228 */
211 fence_owner = amdgpu_sync_get_owner(f);
212 if ((owner != AMDGPU_FENCE_OWNER_UNDEFINED) && 229 if ((owner != AMDGPU_FENCE_OWNER_UNDEFINED) &&
213 (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED) && 230 (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED) &&
214 ((owner == AMDGPU_FENCE_OWNER_VM) != 231 ((owner == AMDGPU_FENCE_OWNER_VM) !=
@@ -305,6 +322,41 @@ struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit
305 return NULL; 322 return NULL;
306} 323}
307 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 */
334int 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
308int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr) 360int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr)
309{ 361{
310 struct amdgpu_sync_entry *e; 362 struct amdgpu_sync_entry *e;