diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 56 |
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 | ||
35 | struct amdgpu_sync_entry { | 36 | struct 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 | */ |
86 | static void *amdgpu_sync_get_owner(struct dma_fence *f) | 87 | static 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 | */ | ||
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 | |||
308 | int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr) | 360 | int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr) |
309 | { | 361 | { |
310 | struct amdgpu_sync_entry *e; | 362 | struct amdgpu_sync_entry *e; |