xref: /linux/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c (revision 0856cab1a6298d9cbf037dc683ce514cadb28040)
1*0856cab1SChristian König /*
2*0856cab1SChristian König  * Copyright 2015 Advanced Micro Devices, Inc.
3*0856cab1SChristian König  *
4*0856cab1SChristian König  * Permission is hereby granted, free of charge, to any person obtaining a
5*0856cab1SChristian König  * copy of this software and associated documentation files (the "Software"),
6*0856cab1SChristian König  * to deal in the Software without restriction, including without limitation
7*0856cab1SChristian König  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*0856cab1SChristian König  * and/or sell copies of the Software, and to permit persons to whom the
9*0856cab1SChristian König  * Software is furnished to do so, subject to the following conditions:
10*0856cab1SChristian König  *
11*0856cab1SChristian König  * The above copyright notice and this permission notice shall be included in
12*0856cab1SChristian König  * all copies or substantial portions of the Software.
13*0856cab1SChristian König  *
14*0856cab1SChristian König  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*0856cab1SChristian König  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*0856cab1SChristian König  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*0856cab1SChristian König  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*0856cab1SChristian König  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*0856cab1SChristian König  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*0856cab1SChristian König  * OTHER DEALINGS IN THE SOFTWARE.
21*0856cab1SChristian König  *
22*0856cab1SChristian König  *
23*0856cab1SChristian König  */
24*0856cab1SChristian König #include <linux/kthread.h>
25*0856cab1SChristian König #include <linux/wait.h>
26*0856cab1SChristian König #include <linux/sched.h>
27*0856cab1SChristian König #include <drm/drmP.h>
28*0856cab1SChristian König #include "amdgpu.h"
29*0856cab1SChristian König #include "amdgpu_trace.h"
30*0856cab1SChristian König 
31*0856cab1SChristian König int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
32*0856cab1SChristian König 		     struct amdgpu_job **job)
33*0856cab1SChristian König {
34*0856cab1SChristian König 	size_t size = sizeof(struct amdgpu_job);
35*0856cab1SChristian König 
36*0856cab1SChristian König 	if (num_ibs == 0)
37*0856cab1SChristian König 		return -EINVAL;
38*0856cab1SChristian König 
39*0856cab1SChristian König 	size += sizeof(struct amdgpu_ib) * num_ibs;
40*0856cab1SChristian König 
41*0856cab1SChristian König 	*job = kzalloc(size, GFP_KERNEL);
42*0856cab1SChristian König 	if (!*job)
43*0856cab1SChristian König 		return -ENOMEM;
44*0856cab1SChristian König 
45*0856cab1SChristian König 	(*job)->adev = adev;
46*0856cab1SChristian König 	(*job)->ibs = (void *)&(*job)[1];
47*0856cab1SChristian König 	(*job)->num_ibs = num_ibs;
48*0856cab1SChristian König 
49*0856cab1SChristian König 	return 0;
50*0856cab1SChristian König }
51*0856cab1SChristian König 
52*0856cab1SChristian König int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
53*0856cab1SChristian König 			     struct amdgpu_job **job)
54*0856cab1SChristian König {
55*0856cab1SChristian König 	int r;
56*0856cab1SChristian König 
57*0856cab1SChristian König 	r = amdgpu_job_alloc(adev, 1, job);
58*0856cab1SChristian König 	if (r)
59*0856cab1SChristian König 		return r;
60*0856cab1SChristian König 
61*0856cab1SChristian König 	r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
62*0856cab1SChristian König 	if (r)
63*0856cab1SChristian König 		kfree(*job);
64*0856cab1SChristian König 
65*0856cab1SChristian König 	return r;
66*0856cab1SChristian König }
67*0856cab1SChristian König 
68*0856cab1SChristian König void amdgpu_job_free(struct amdgpu_job *job)
69*0856cab1SChristian König {
70*0856cab1SChristian König 	unsigned i;
71*0856cab1SChristian König 
72*0856cab1SChristian König 	for (i = 0; i < job->num_ibs; ++i)
73*0856cab1SChristian König 		amdgpu_ib_free(job->adev, &job->ibs[i]);
74*0856cab1SChristian König 
75*0856cab1SChristian König 	amdgpu_bo_unref(&job->uf.bo);
76*0856cab1SChristian König 	kfree(job);
77*0856cab1SChristian König }
78*0856cab1SChristian König 
79*0856cab1SChristian König int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring,
80*0856cab1SChristian König 		      void *owner, struct fence **f)
81*0856cab1SChristian König {
82*0856cab1SChristian König 	struct amdgpu_device *adev = job->adev;
83*0856cab1SChristian König 
84*0856cab1SChristian König 	job->ring = ring;
85*0856cab1SChristian König 	job->base.sched = &ring->sched;
86*0856cab1SChristian König 	job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity;
87*0856cab1SChristian König 	job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner);
88*0856cab1SChristian König 	if (!job->base.s_fence)
89*0856cab1SChristian König 		return -ENOMEM;
90*0856cab1SChristian König 
91*0856cab1SChristian König 	*f = fence_get(&job->base.s_fence->base);
92*0856cab1SChristian König 
93*0856cab1SChristian König 	job->owner = owner;
94*0856cab1SChristian König 	amd_sched_entity_push_job(&job->base);
95*0856cab1SChristian König 
96*0856cab1SChristian König 	return 0;
97*0856cab1SChristian König }
98*0856cab1SChristian König 
99*0856cab1SChristian König static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job)
100*0856cab1SChristian König {
101*0856cab1SChristian König 	struct amdgpu_job *job = to_amdgpu_job(sched_job);
102*0856cab1SChristian König 	struct amdgpu_sync *sync = &job->ibs->sync;
103*0856cab1SChristian König 	struct amdgpu_vm *vm = job->ibs->vm;
104*0856cab1SChristian König 
105*0856cab1SChristian König 	struct fence *fence = amdgpu_sync_get_fence(sync);
106*0856cab1SChristian König 
107*0856cab1SChristian König 	if (fence == NULL && vm && !job->ibs->grabbed_vmid) {
108*0856cab1SChristian König 		struct amdgpu_ring *ring = job->ring;
109*0856cab1SChristian König 		int r;
110*0856cab1SChristian König 
111*0856cab1SChristian König 		r = amdgpu_vm_grab_id(vm, ring, sync,
112*0856cab1SChristian König 				      &job->base.s_fence->base);
113*0856cab1SChristian König 		if (r)
114*0856cab1SChristian König 			DRM_ERROR("Error getting VM ID (%d)\n", r);
115*0856cab1SChristian König 		else
116*0856cab1SChristian König 			job->ibs->grabbed_vmid = true;
117*0856cab1SChristian König 
118*0856cab1SChristian König 		fence = amdgpu_sync_get_fence(sync);
119*0856cab1SChristian König 	}
120*0856cab1SChristian König 
121*0856cab1SChristian König 	return fence;
122*0856cab1SChristian König }
123*0856cab1SChristian König 
124*0856cab1SChristian König static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job)
125*0856cab1SChristian König {
126*0856cab1SChristian König 	struct fence *fence = NULL;
127*0856cab1SChristian König 	struct amdgpu_job *job;
128*0856cab1SChristian König 	int r;
129*0856cab1SChristian König 
130*0856cab1SChristian König 	if (!sched_job) {
131*0856cab1SChristian König 		DRM_ERROR("job is null\n");
132*0856cab1SChristian König 		return NULL;
133*0856cab1SChristian König 	}
134*0856cab1SChristian König 	job = to_amdgpu_job(sched_job);
135*0856cab1SChristian König 	trace_amdgpu_sched_run_job(job);
136*0856cab1SChristian König 	r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs,
137*0856cab1SChristian König 			       job->owner, &fence);
138*0856cab1SChristian König 	if (r) {
139*0856cab1SChristian König 		DRM_ERROR("Error scheduling IBs (%d)\n", r);
140*0856cab1SChristian König 		goto err;
141*0856cab1SChristian König 	}
142*0856cab1SChristian König 
143*0856cab1SChristian König err:
144*0856cab1SChristian König 	amdgpu_job_free(job);
145*0856cab1SChristian König 	return fence;
146*0856cab1SChristian König }
147*0856cab1SChristian König 
148*0856cab1SChristian König struct amd_sched_backend_ops amdgpu_sched_ops = {
149*0856cab1SChristian König 	.dependency = amdgpu_job_dependency,
150*0856cab1SChristian König 	.run_job = amdgpu_job_run,
151*0856cab1SChristian König };
152