drm/amdgpu: wake up scheduler only when neccessary
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_sched.c
CommitLineData
c1b69ed0
CZ
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 *
23 */
24#include <linux/kthread.h>
25#include <linux/wait.h>
26#include <linux/sched.h>
27#include <drm/drmP.h>
28#include "amdgpu.h"
29
6f0e54a9
CK
30static struct fence *amdgpu_sched_run_job(struct amd_gpu_scheduler *sched,
31 struct amd_sched_entity *entity,
32 struct amd_sched_job *job)
c1b69ed0
CZ
33{
34 int r = 0;
bb977d37 35 struct amdgpu_job *sched_job;
7484667c 36 struct amdgpu_fence *fence;
c1b69ed0 37
bb977d37 38 if (!job) {
4cef9267 39 DRM_ERROR("job is null\n");
6f0e54a9 40 return NULL;
4cef9267 41 }
bb977d37 42 sched_job = (struct amdgpu_job *)job;
c1b69ed0
CZ
43 mutex_lock(&sched_job->job_lock);
44 r = amdgpu_ib_schedule(sched_job->adev,
45 sched_job->num_ibs,
46 sched_job->ibs,
84f76ea6 47 sched_job->base.owner);
c1b69ed0
CZ
48 if (r)
49 goto err;
6f0e54a9 50 fence = amdgpu_fence_ref(sched_job->ibs[sched_job->num_ibs - 1].fence);
7484667c 51
bf7ebaee
CK
52 if (sched_job->free_job)
53 sched_job->free_job(sched_job);
54
c1b69ed0 55 mutex_unlock(&sched_job->job_lock);
6f0e54a9
CK
56 return &fence->base;
57
c1b69ed0
CZ
58err:
59 DRM_ERROR("Run job error\n");
60 mutex_unlock(&sched_job->job_lock);
bb977d37 61 sched->ops->process_job(sched, (struct amd_sched_job *)sched_job);
6f0e54a9 62 return NULL;
c1b69ed0
CZ
63}
64
953e8fd4
CZ
65static void amdgpu_sched_process_job(struct amd_gpu_scheduler *sched,
66 struct amd_sched_job *job)
c1b69ed0 67{
bb977d37 68 struct amdgpu_job *sched_job;
c1b69ed0 69
bb977d37 70 if (!job) {
953e8fd4 71 DRM_ERROR("job is null\n");
c1b69ed0 72 return;
953e8fd4 73 }
bb977d37 74 sched_job = (struct amdgpu_job *)job;
bb977d37
CZ
75 /* after processing job, free memory */
76 fence_put(&sched_job->base.s_fence->base);
77 kfree(sched_job);
c1b69ed0
CZ
78}
79
80struct amd_sched_backend_ops amdgpu_sched_ops = {
c1b69ed0
CZ
81 .run_job = amdgpu_sched_run_job,
82 .process_job = amdgpu_sched_process_job
83};
84
3c704e93
CZ
85int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,
86 struct amdgpu_ring *ring,
87 struct amdgpu_ib *ibs,
88 unsigned num_ibs,
bb977d37 89 int (*free_job)(struct amdgpu_job *),
1763552e
CZ
90 void *owner,
91 struct fence **f)
3c704e93
CZ
92{
93 int r = 0;
94 if (amdgpu_enable_scheduler) {
bb977d37
CZ
95 struct amdgpu_job *job =
96 kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);
97 if (!job)
3c704e93 98 return -ENOMEM;
bb977d37
CZ
99 job->base.sched = ring->scheduler;
100 job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity;
101 job->adev = adev;
102 job->ibs = ibs;
103 job->num_ibs = num_ibs;
84f76ea6 104 job->base.owner = owner;
bb977d37
CZ
105 mutex_init(&job->job_lock);
106 job->free_job = free_job;
107 mutex_lock(&job->job_lock);
6c859274 108 r = amd_sched_entity_push_job((struct amd_sched_job *)job);
f556cb0c 109 if (r) {
bb977d37
CZ
110 mutex_unlock(&job->job_lock);
111 kfree(job);
f556cb0c
CZ
112 return r;
113 }
bb977d37
CZ
114 *f = fence_get(&job->base.s_fence->base);
115 mutex_unlock(&job->job_lock);
f556cb0c 116 } else {
4af9f07c 117 r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner);
f556cb0c
CZ
118 if (r)
119 return r;
281b4223 120 *f = fence_get(&ibs[num_ibs - 1].fence->base);
f556cb0c 121 }
3c62338c 122
1763552e 123 return 0;
3c704e93 124}