aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0244-drm-amdgpu-only-support-IBs-in-the-buffer-list-v2.patch
blob: ac4198ed67b017f43bc3f344b94f0be60676f343 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
From 3ccec53c294cbec2af44b6b24f70349637c45428 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= <marek.olsak@amd.com>
Date: Tue, 2 Jun 2015 17:44:49 +0200
Subject: [PATCH 0244/1050] drm/amdgpu: only support IBs in the buffer list
 (v2)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

amdgpu_cs_find_mapping doesn't work without all buffers being validated,
so the TTM validation must be done first.

v2: only use amdgpu_cs_find_mapping for UVD/VCE VM emulation

Signed-off-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h    |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 95 +++++++++-------------------------
 2 files changed, 24 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 149b769..c33c1af3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1191,7 +1191,6 @@ struct amdgpu_cs_parser {
 	struct amdgpu_cs_chunk	*chunks;
 	/* relocations */
 	struct amdgpu_bo_list_entry	*vm_bos;
-	struct amdgpu_bo_list_entry	*ib_bos;
 	struct list_head	validated;
 
 	struct amdgpu_ib	*ibs;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index fefa48a..f6b224a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -230,11 +230,6 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 		goto out;
 	}
 
-	p->ib_bos = kcalloc(p->num_ibs, sizeof(struct amdgpu_bo_list_entry),
-			    GFP_KERNEL);
-	if (!p->ib_bos)
-		r = -ENOMEM;
-
 out:
 	kfree(chunk_array);
 	return r;
@@ -373,13 +368,6 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
 	p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
 				      &p->validated);
 
-	for (i = 0; i < p->num_ibs; i++) {
-		if (!p->ib_bos[i].robj)
-			continue;
-
-		list_add(&p->ib_bos[i].tv.head, &p->validated);
-	}
-
 	if (need_mmap_lock)
 		down_read(&current->mm->mmap_sem);
 
@@ -457,15 +445,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
 	for (i = 0; i < parser->nchunks; i++)
 		drm_free_large(parser->chunks[i].kdata);
 	kfree(parser->chunks);
-	for (i = 0; i < parser->num_ibs; i++) {
-		struct amdgpu_bo *bo = parser->ib_bos[i].robj;
+	for (i = 0; i < parser->num_ibs; i++)
 		amdgpu_ib_free(parser->adev, &parser->ibs[i]);
-
-		if (bo)
-			drm_gem_object_unreference_unlocked(&bo->gem_base);
-	}
 	kfree(parser->ibs);
-	kfree(parser->ib_bos);
 	if (parser->uf.bo)
 		drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base);
 }
@@ -505,21 +487,6 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
 		}
 	}
 
-	for (i = 0; i < p->num_ibs; i++) {
-		bo = p->ib_bos[i].robj;
-		if (!bo)
-			continue;
-
-		bo_va = p->ib_bos[i].bo_va;
-		if (!bo_va)
-			continue;
-
-		r = amdgpu_vm_bo_update(adev, bo_va, &bo->tbo.mem);
-		if (r)
-			return r;
-
-		amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update);
-	}
 	return amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync);
 }
 
@@ -581,11 +548,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
 		struct amdgpu_cs_chunk *chunk;
 		struct amdgpu_ib *ib;
 		struct drm_amdgpu_cs_chunk_ib *chunk_ib;
-		struct amdgpu_bo_list_entry *ib_bo;
 		struct amdgpu_ring *ring;
-		struct drm_gem_object *gobj;
-		struct amdgpu_bo *aobj;
-		void *kptr;
 
 		chunk = &parser->chunks[i];
 		ib = &parser->ibs[j];
@@ -594,66 +557,49 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
 		if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
 			continue;
 
-		gobj = drm_gem_object_lookup(adev->ddev, parser->filp, chunk_ib->handle);
-		if (gobj == NULL)
-			return -ENOENT;
-		aobj = gem_to_amdgpu_bo(gobj);
-
 		r = amdgpu_cs_get_ring(adev, chunk_ib->ip_type,
 				       chunk_ib->ip_instance, chunk_ib->ring,
 				       &ring);
-		if (r) {
-			drm_gem_object_unreference_unlocked(gobj);
+		if (r)
 			return r;
-		}
 
 		if (ring->funcs->parse_cs) {
-			r = amdgpu_bo_reserve(aobj, false);
-			if (r) {
-				drm_gem_object_unreference_unlocked(gobj);
-				return r;
+			struct amdgpu_bo *aobj = NULL;
+			void *kptr;
+
+			amdgpu_cs_find_mapping(parser, chunk_ib->va_start, &aobj);
+			if (!aobj) {
+				DRM_ERROR("IB va_start is invalid\n");
+				return -EINVAL;
 			}
 
+			/* the IB should be reserved at this point */
 			r = amdgpu_bo_kmap(aobj, &kptr);
 			if (r) {
-				amdgpu_bo_unreserve(aobj);
-				drm_gem_object_unreference_unlocked(gobj);
 				return r;
 			}
 
 			r =  amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib);
 			if (r) {
 				DRM_ERROR("Failed to get ib !\n");
-				amdgpu_bo_unreserve(aobj);
-				drm_gem_object_unreference_unlocked(gobj);
 				return r;
 			}
 
 			memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
 			amdgpu_bo_kunmap(aobj);
-			amdgpu_bo_unreserve(aobj);
 		} else {
 			r =  amdgpu_ib_get(ring, vm, 0, ib);
 			if (r) {
 				DRM_ERROR("Failed to get ib !\n");
-				drm_gem_object_unreference_unlocked(gobj);
 				return r;
 			}
 
 			ib->gpu_addr = chunk_ib->va_start;
 		}
-		ib->length_dw = chunk_ib->ib_bytes / 4;
 
+		ib->length_dw = chunk_ib->ib_bytes / 4;
 		ib->flags = chunk_ib->flags;
 		ib->ctx = parser->ctx;
-
-		ib_bo = &parser->ib_bos[j];
-		ib_bo->robj = aobj;
-		ib_bo->prefered_domains = aobj->initial_domain;
-		ib_bo->allowed_domains = aobj->initial_domain;
-		ib_bo->priority = 0;
-		ib_bo->tv.bo = &aobj->tbo;
-		ib_bo->tv.shared = true;
 		j++;
 	}
 
@@ -702,6 +648,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 	union drm_amdgpu_cs *cs = data;
 	struct amdgpu_cs_parser parser;
 	int r, i;
+	bool reserved_buffers = false;
 
 	down_read(&adev->exclusive_lock);
 	if (!adev->accel_working) {
@@ -721,15 +668,21 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 		return r;
 	}
 
-	r = amdgpu_cs_ib_fill(adev, &parser);
-	if (!r) {
-		r = amdgpu_cs_parser_relocs(&parser);
-		if (r && r != -ERESTARTSYS)
-			DRM_ERROR("Failed to parse relocation %d!\n", r);
+	r = amdgpu_cs_parser_relocs(&parser);
+	if (r) {
+		if (r != -ERESTARTSYS) {
+			if (r == -ENOMEM)
+				DRM_ERROR("Not enough memory for command submission!\n");
+			else
+				DRM_ERROR("Failed to process the buffer list %d!\n", r);
+		}
+	} else {
+		reserved_buffers = true;
+		r = amdgpu_cs_ib_fill(adev, &parser);
 	}
 
 	if (r) {
-		amdgpu_cs_parser_fini(&parser, r, false);
+		amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
 		up_read(&adev->exclusive_lock);
 		r = amdgpu_cs_handle_lockup(adev, r);
 		return r;
-- 
1.9.1