diff options
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 5 |
4 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 412fc2f39fa5..9bf72b24495c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -2401,5 +2401,4 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, | |||
2401 | uint64_t addr, struct amdgpu_bo **bo); | 2401 | uint64_t addr, struct amdgpu_bo **bo); |
2402 | 2402 | ||
2403 | #include "amdgpu_object.h" | 2403 | #include "amdgpu_object.h" |
2404 | |||
2405 | #endif | 2404 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index eb0f7890401a..23468088a995 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
@@ -28,6 +28,12 @@ | |||
28 | #include "amdgpu.h" | 28 | #include "amdgpu.h" |
29 | #include "amdgpu_trace.h" | 29 | #include "amdgpu_trace.h" |
30 | 30 | ||
31 | static void amdgpu_job_free_handler(struct work_struct *ws) | ||
32 | { | ||
33 | struct amdgpu_job *job = container_of(ws, struct amdgpu_job, base.work_free_job); | ||
34 | kfree(job); | ||
35 | } | ||
36 | |||
31 | int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | 37 | int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, |
32 | struct amdgpu_job **job) | 38 | struct amdgpu_job **job) |
33 | { | 39 | { |
@@ -45,6 +51,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | |||
45 | (*job)->adev = adev; | 51 | (*job)->adev = adev; |
46 | (*job)->ibs = (void *)&(*job)[1]; | 52 | (*job)->ibs = (void *)&(*job)[1]; |
47 | (*job)->num_ibs = num_ibs; | 53 | (*job)->num_ibs = num_ibs; |
54 | INIT_WORK(&(*job)->base.work_free_job, amdgpu_job_free_handler); | ||
48 | 55 | ||
49 | amdgpu_sync_create(&(*job)->sync); | 56 | amdgpu_sync_create(&(*job)->sync); |
50 | 57 | ||
@@ -80,7 +87,9 @@ void amdgpu_job_free(struct amdgpu_job *job) | |||
80 | 87 | ||
81 | amdgpu_bo_unref(&job->uf.bo); | 88 | amdgpu_bo_unref(&job->uf.bo); |
82 | amdgpu_sync_free(&job->sync); | 89 | amdgpu_sync_free(&job->sync); |
83 | kfree(job); | 90 | |
91 | if (!job->base.use_sched) | ||
92 | kfree(job); | ||
84 | } | 93 | } |
85 | 94 | ||
86 | int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, | 95 | int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index b9d5822bece8..8d49ea2e4134 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -319,6 +319,11 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job) | |||
319 | return added; | 319 | return added; |
320 | } | 320 | } |
321 | 321 | ||
322 | static void amd_sched_free_job(struct fence *f, struct fence_cb *cb) { | ||
323 | struct amd_sched_job *job = container_of(cb, struct amd_sched_job, cb_free_job); | ||
324 | schedule_work(&job->work_free_job); | ||
325 | } | ||
326 | |||
322 | /** | 327 | /** |
323 | * Submit a job to the job queue | 328 | * Submit a job to the job queue |
324 | * | 329 | * |
@@ -330,6 +335,9 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job) | |||
330 | { | 335 | { |
331 | struct amd_sched_entity *entity = sched_job->s_entity; | 336 | struct amd_sched_entity *entity = sched_job->s_entity; |
332 | 337 | ||
338 | sched_job->use_sched = 1; | ||
339 | fence_add_callback(&sched_job->s_fence->base, | ||
340 | &sched_job->cb_free_job, amd_sched_free_job); | ||
333 | trace_amd_sched_job(sched_job); | 341 | trace_amd_sched_job(sched_job); |
334 | wait_event(entity->sched->job_scheduled, | 342 | wait_event(entity->sched->job_scheduled, |
335 | amd_sched_entity_in(sched_job)); | 343 | amd_sched_entity_in(sched_job)); |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index 74bbec837f58..ee1e8127f863 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | |||
@@ -37,7 +37,7 @@ extern atomic_t sched_fence_slab_ref; | |||
37 | 37 | ||
38 | /** | 38 | /** |
39 | * A scheduler entity is a wrapper around a job queue or a group | 39 | * A scheduler entity is a wrapper around a job queue or a group |
40 | * of other entities. Entities take turns emitting jobs from their | 40 | * of other entities. Entities take turns emitting jobs from their |
41 | * job queues to corresponding hardware ring based on scheduling | 41 | * job queues to corresponding hardware ring based on scheduling |
42 | * policy. | 42 | * policy. |
43 | */ | 43 | */ |
@@ -82,6 +82,9 @@ struct amd_sched_job { | |||
82 | struct amd_gpu_scheduler *sched; | 82 | struct amd_gpu_scheduler *sched; |
83 | struct amd_sched_entity *s_entity; | 83 | struct amd_sched_entity *s_entity; |
84 | struct amd_sched_fence *s_fence; | 84 | struct amd_sched_fence *s_fence; |
85 | bool use_sched; /* true if the job goes to scheduler */ | ||
86 | struct fence_cb cb_free_job; | ||
87 | struct work_struct work_free_job; | ||
85 | }; | 88 | }; |
86 | 89 | ||
87 | extern const struct fence_ops amd_sched_fence_ops; | 90 | extern const struct fence_ops amd_sched_fence_ops; |