aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMonk Liu <Monk.Liu@amd.com>2016-03-03 06:00:50 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-05-02 15:17:41 -0400
commite472d2588eef38c2f16f71d6160e58fb5948e84f (patch)
treea2459eecb00bb9772dca675e87127706f97a3058
parent01c02a8b193d63d77e0b45886efa71c9983af446 (diff)
drm/amdgpu: delay job free to when it's finished (v2)
for those jobs submitted through scheduler, do not free it immediately after scheduled, instead free it in global workqueue by its sched fence signaling callback function. v2: call uf's bo_undef after job_run() call job's sync free after job_run() no static inline __amdgpu_job_free() anymore, just use kfree(job) to replace it. Signed-off-by: Monk Liu <Monk.Liu@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c11
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.c8
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.h5
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
31static 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
31int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, 37int 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
86int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, 95int 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
322static 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
87extern const struct fence_ops amd_sched_fence_ops; 90extern const struct fence_ops amd_sched_fence_ops;