diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 3 |
5 files changed, 55 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index aa2dcf578dd6..719506808b4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -717,6 +717,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
717 | void *owner); | 717 | void *owner); |
718 | int amdgpu_sync_rings(struct amdgpu_sync *sync, | 718 | int amdgpu_sync_rings(struct amdgpu_sync *sync, |
719 | struct amdgpu_ring *ring); | 719 | struct amdgpu_ring *ring); |
720 | struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); | ||
720 | int amdgpu_sync_wait(struct amdgpu_sync *sync); | 721 | int amdgpu_sync_wait(struct amdgpu_sync *sync); |
721 | void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync, | 722 | void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync, |
722 | struct fence *fence); | 723 | struct fence *fence); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index f93fb3541488..de98fbd2971e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -27,6 +27,12 @@ | |||
27 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
28 | #include "amdgpu.h" | 28 | #include "amdgpu.h" |
29 | 29 | ||
30 | static struct fence *amdgpu_sched_dependency(struct amd_sched_job *job) | ||
31 | { | ||
32 | struct amdgpu_job *sched_job = (struct amdgpu_job *)job; | ||
33 | return amdgpu_sync_get_fence(&sched_job->ibs->sync); | ||
34 | } | ||
35 | |||
30 | static struct fence *amdgpu_sched_run_job(struct amd_sched_job *job) | 36 | static struct fence *amdgpu_sched_run_job(struct amd_sched_job *job) |
31 | { | 37 | { |
32 | struct amdgpu_job *sched_job; | 38 | struct amdgpu_job *sched_job; |
@@ -75,6 +81,7 @@ static void amdgpu_sched_process_job(struct amd_sched_job *job) | |||
75 | } | 81 | } |
76 | 82 | ||
77 | struct amd_sched_backend_ops amdgpu_sched_ops = { | 83 | struct amd_sched_backend_ops amdgpu_sched_ops = { |
84 | .dependency = amdgpu_sched_dependency, | ||
78 | .run_job = amdgpu_sched_run_job, | 85 | .run_job = amdgpu_sched_run_job, |
79 | .process_job = amdgpu_sched_process_job | 86 | .process_job = amdgpu_sched_process_job |
80 | }; | 87 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index 4fffb2539331..69b7d4540c6e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
@@ -202,6 +202,28 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
202 | return r; | 202 | return r; |
203 | } | 203 | } |
204 | 204 | ||
205 | struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync) | ||
206 | { | ||
207 | struct amdgpu_sync_entry *e; | ||
208 | struct hlist_node *tmp; | ||
209 | struct fence *f; | ||
210 | int i; | ||
211 | |||
212 | hash_for_each_safe(sync->fences, i, tmp, e, node) { | ||
213 | |||
214 | f = e->fence; | ||
215 | |||
216 | hash_del(&e->node); | ||
217 | kfree(e); | ||
218 | |||
219 | if (!fence_is_signaled(f)) | ||
220 | return f; | ||
221 | |||
222 | fence_put(f); | ||
223 | } | ||
224 | return NULL; | ||
225 | } | ||
226 | |||
205 | int amdgpu_sync_wait(struct amdgpu_sync *sync) | 227 | int amdgpu_sync_wait(struct amdgpu_sync *sync) |
206 | { | 228 | { |
207 | struct amdgpu_sync_entry *e; | 229 | struct amdgpu_sync_entry *e; |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 205cb887d023..2f5d1f0da8e5 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -192,14 +192,36 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, | |||
192 | kfifo_free(&entity->job_queue); | 192 | kfifo_free(&entity->job_queue); |
193 | } | 193 | } |
194 | 194 | ||
195 | static void amd_sched_entity_wakeup(struct fence *f, struct fence_cb *cb) | ||
196 | { | ||
197 | struct amd_sched_entity *entity = | ||
198 | container_of(cb, struct amd_sched_entity, cb); | ||
199 | entity->dependency = NULL; | ||
200 | fence_put(f); | ||
201 | amd_sched_wakeup(entity->scheduler); | ||
202 | } | ||
203 | |||
195 | static struct amd_sched_job * | 204 | static struct amd_sched_job * |
196 | amd_sched_entity_pop_job(struct amd_sched_entity *entity) | 205 | amd_sched_entity_pop_job(struct amd_sched_entity *entity) |
197 | { | 206 | { |
207 | struct amd_gpu_scheduler *sched = entity->scheduler; | ||
198 | struct amd_sched_job *job; | 208 | struct amd_sched_job *job; |
199 | 209 | ||
210 | if (ACCESS_ONCE(entity->dependency)) | ||
211 | return NULL; | ||
212 | |||
200 | if (!kfifo_out_peek(&entity->job_queue, &job, sizeof(job))) | 213 | if (!kfifo_out_peek(&entity->job_queue, &job, sizeof(job))) |
201 | return NULL; | 214 | return NULL; |
202 | 215 | ||
216 | while ((entity->dependency = sched->ops->dependency(job))) { | ||
217 | |||
218 | if (fence_add_callback(entity->dependency, &entity->cb, | ||
219 | amd_sched_entity_wakeup)) | ||
220 | fence_put(entity->dependency); | ||
221 | else | ||
222 | return NULL; | ||
223 | } | ||
224 | |||
203 | return job; | 225 | return job; |
204 | } | 226 | } |
205 | 227 | ||
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index e797796dcad7..2af0e4d4d817 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | |||
@@ -45,6 +45,8 @@ struct amd_sched_entity { | |||
45 | spinlock_t queue_lock; | 45 | spinlock_t queue_lock; |
46 | struct amd_gpu_scheduler *scheduler; | 46 | struct amd_gpu_scheduler *scheduler; |
47 | uint64_t fence_context; | 47 | uint64_t fence_context; |
48 | struct fence *dependency; | ||
49 | struct fence_cb cb; | ||
48 | }; | 50 | }; |
49 | 51 | ||
50 | /** | 52 | /** |
@@ -89,6 +91,7 @@ static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) | |||
89 | * these functions should be implemented in driver side | 91 | * these functions should be implemented in driver side |
90 | */ | 92 | */ |
91 | struct amd_sched_backend_ops { | 93 | struct amd_sched_backend_ops { |
94 | struct fence *(*dependency)(struct amd_sched_job *job); | ||
92 | struct fence *(*run_job)(struct amd_sched_job *job); | 95 | struct fence *(*run_job)(struct amd_sched_job *job); |
93 | void (*process_job)(struct amd_sched_job *job); | 96 | void (*process_job)(struct amd_sched_job *job); |
94 | }; | 97 | }; |