Rev 5078 | Rev 5346 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 5271 | ||
---|---|---|---|
Line 82... | Line 82... | ||
82 | static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) |
82 | static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) |
83 | { |
83 | { |
84 | struct drm_device *ddev = p->rdev->ddev; |
84 | struct drm_device *ddev = p->rdev->ddev; |
85 | struct radeon_cs_chunk *chunk; |
85 | struct radeon_cs_chunk *chunk; |
86 | struct radeon_cs_buckets buckets; |
86 | struct radeon_cs_buckets buckets; |
87 | unsigned i, j; |
87 | unsigned i; |
88 | bool duplicate; |
88 | bool need_mmap_lock = false; |
- | 89 | int r; |
|
Line 89... | Line 90... | ||
89 | 90 | ||
90 | if (p->chunk_relocs_idx == -1) { |
91 | if (p->chunk_relocs == NULL) { |
91 | return 0; |
92 | return 0; |
92 | } |
93 | } |
93 | chunk = &p->chunks[p->chunk_relocs_idx]; |
94 | chunk = p->chunk_relocs; |
94 | p->dma_reloc_idx = 0; |
95 | p->dma_reloc_idx = 0; |
95 | /* FIXME: we assume that each relocs use 4 dwords */ |
96 | /* FIXME: we assume that each relocs use 4 dwords */ |
96 | p->nrelocs = chunk->length_dw / 4; |
- | |
97 | p->relocs_ptr = kcalloc(p->nrelocs, sizeof(void *), GFP_KERNEL); |
- | |
98 | if (p->relocs_ptr == NULL) { |
- | |
99 | return -ENOMEM; |
- | |
100 | } |
97 | p->nrelocs = chunk->length_dw / 4; |
101 | p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL); |
98 | p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_bo_list), GFP_KERNEL); |
102 | if (p->relocs == NULL) { |
99 | if (p->relocs == NULL) { |
103 | return -ENOMEM; |
100 | return -ENOMEM; |
Line 104... | Line 101... | ||
104 | } |
101 | } |
Line 105... | Line 102... | ||
105 | 102 | ||
106 | radeon_cs_buckets_init(&buckets); |
103 | radeon_cs_buckets_init(&buckets); |
- | 104 | ||
107 | 105 | for (i = 0; i < p->nrelocs; i++) { |
|
Line 108... | Line -... | ||
108 | for (i = 0; i < p->nrelocs; i++) { |
- | |
109 | struct drm_radeon_cs_reloc *r; |
106 | struct drm_radeon_cs_reloc *r; |
110 | unsigned priority; |
- | |
111 | - | ||
112 | duplicate = false; |
- | |
113 | r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; |
- | |
114 | for (j = 0; j < i; j++) { |
- | |
115 | if (r->handle == p->relocs[j].handle) { |
- | |
116 | p->relocs_ptr[i] = &p->relocs[j]; |
- | |
117 | duplicate = true; |
- | |
118 | break; |
- | |
119 | } |
- | |
120 | } |
- | |
121 | if (duplicate) { |
- | |
122 | p->relocs[i].handle = 0; |
107 | struct drm_gem_object *gobj; |
123 | continue; |
- | |
124 | } |
108 | unsigned priority; |
125 | 109 | ||
126 | p->relocs[i].gobj = drm_gem_object_lookup(ddev, p->filp, |
110 | r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; |
127 | r->handle); |
111 | gobj = drm_gem_object_lookup(ddev, p->filp, r->handle); |
128 | if (p->relocs[i].gobj == NULL) { |
112 | if (gobj == NULL) { |
129 | DRM_ERROR("gem object lookup failed 0x%x\n", |
- | |
130 | r->handle); |
113 | DRM_ERROR("gem object lookup failed 0x%x\n", |
Line 131... | Line 114... | ||
131 | return -ENOENT; |
114 | r->handle); |
132 | } |
115 | return -ENOENT; |
133 | p->relocs_ptr[i] = &p->relocs[i]; |
116 | } |
134 | p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj); |
117 | p->relocs[i].robj = gem_to_radeon_bo(gobj); |
Line 141... | Line 124... | ||
141 | */ |
124 | */ |
142 | priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2 |
125 | priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2 |
143 | + !!r->write_domain; |
126 | + !!r->write_domain; |
Line 144... | Line 127... | ||
144 | 127 | ||
145 | /* the first reloc of an UVD job is the msg and that must be in |
128 | /* the first reloc of an UVD job is the msg and that must be in |
146 | VRAM, also but everything into VRAM on AGP cards to avoid |
129 | VRAM, also but everything into VRAM on AGP cards and older |
147 | image corruptions */ |
130 | IGP chips to avoid image corruptions */ |
148 | if (p->ring == R600_RING_TYPE_UVD_INDEX && |
131 | if (p->ring == R600_RING_TYPE_UVD_INDEX && |
- | 132 | (i == 0 || drm_pci_device_is_agp(p->rdev->ddev) || |
|
- | 133 | p->rdev->family == CHIP_RS780 || |
|
- | 134 | p->rdev->family == CHIP_RS880)) { |
|
149 | (i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) { |
135 | |
150 | /* TODO: is this still needed for NI+ ? */ |
136 | /* TODO: is this still needed for NI+ ? */ |
151 | p->relocs[i].prefered_domains = |
137 | p->relocs[i].prefered_domains = |
Line 152... | Line 138... | ||
152 | RADEON_GEM_DOMAIN_VRAM; |
138 | RADEON_GEM_DOMAIN_VRAM; |
Line 169... | Line 155... | ||
169 | p->relocs[i].prefered_domains = domain; |
155 | p->relocs[i].prefered_domains = domain; |
170 | if (domain == RADEON_GEM_DOMAIN_VRAM) |
156 | if (domain == RADEON_GEM_DOMAIN_VRAM) |
171 | domain |= RADEON_GEM_DOMAIN_GTT; |
157 | domain |= RADEON_GEM_DOMAIN_GTT; |
172 | p->relocs[i].allowed_domains = domain; |
158 | p->relocs[i].allowed_domains = domain; |
173 | } |
159 | } |
174 | 160 | /* |
|
- | 161 | if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) { |
|
- | 162 | uint32_t domain = p->relocs[i].prefered_domains; |
|
- | 163 | if (!(domain & RADEON_GEM_DOMAIN_GTT)) { |
|
- | 164 | DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is " |
|
- | 165 | "allowed for userptr BOs\n"); |
|
- | 166 | return -EINVAL; |
|
- | 167 | } |
|
- | 168 | need_mmap_lock = true; |
|
- | 169 | domain = RADEON_GEM_DOMAIN_GTT; |
|
- | 170 | p->relocs[i].prefered_domains = domain; |
|
- | 171 | p->relocs[i].allowed_domains = domain; |
|
- | 172 | } |
|
- | 173 | */ |
|
175 | p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; |
174 | p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; |
176 | p->relocs[i].handle = r->handle; |
175 | p->relocs[i].tv.shared = !r->write_domain; |
Line 177... | Line 176... | ||
177 | 176 | ||
178 | radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, |
177 | radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, |
179 | priority); |
178 | priority); |
Line 180... | Line 179... | ||
180 | } |
179 | } |
Line 181... | Line 180... | ||
181 | 180 | ||
182 | radeon_cs_buckets_get_list(&buckets, &p->validated); |
181 | radeon_cs_buckets_get_list(&buckets, &p->validated); |
183 | 182 | ||
- | 183 | if (p->cs_flags & RADEON_CS_USE_VM) |
|
- | 184 | p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, |
|
- | 185 | &p->validated); |
|
- | 186 | // if (need_mmap_lock) |
|
- | 187 | // down_read(¤t->mm->mmap_sem); |
|
- | 188 | ||
- | 189 | r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring); |
|
Line 184... | Line 190... | ||
184 | if (p->cs_flags & RADEON_CS_USE_VM) |
190 | |
185 | p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, |
191 | // if (need_mmap_lock) |
Line 186... | Line 192... | ||
186 | &p->validated); |
192 | // up_read(¤t->mm->mmap_sem); |
187 | 193 | ||
188 | return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring); |
194 | return r; |
Line 229... | Line 235... | ||
229 | break; |
235 | break; |
230 | } |
236 | } |
231 | return 0; |
237 | return 0; |
232 | } |
238 | } |
Line 233... | Line 239... | ||
233 | 239 | ||
234 | static void radeon_cs_sync_rings(struct radeon_cs_parser *p) |
240 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) |
- | 241 | { |
|
235 | { |
242 | struct radeon_bo_list *reloc; |
Line 236... | Line 243... | ||
236 | int i; |
243 | int r; |
237 | 244 | ||
238 | for (i = 0; i < p->nrelocs; i++) { |
- | |
Line -... | Line 245... | ||
- | 245 | list_for_each_entry(reloc, &p->validated, tv.head) { |
|
239 | if (!p->relocs[i].robj) |
246 | struct reservation_object *resv; |
240 | continue; |
247 | |
- | 248 | resv = reloc->robj->tbo.resv; |
|
- | 249 | r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, |
|
241 | 250 | reloc->tv.shared); |
|
- | 251 | if (r) |
|
242 | radeon_semaphore_sync_to(p->ib.semaphore, |
252 | return r; |
Line 243... | Line 253... | ||
243 | p->relocs[i].robj->tbo.sync_obj); |
253 | } |
244 | } |
254 | return 0; |
245 | } |
255 | } |
Line 258... | Line 268... | ||
258 | } |
268 | } |
259 | /* get chunks */ |
269 | /* get chunks */ |
260 | INIT_LIST_HEAD(&p->validated); |
270 | INIT_LIST_HEAD(&p->validated); |
261 | p->idx = 0; |
271 | p->idx = 0; |
262 | p->ib.sa_bo = NULL; |
272 | p->ib.sa_bo = NULL; |
263 | p->ib.semaphore = NULL; |
- | |
264 | p->const_ib.sa_bo = NULL; |
273 | p->const_ib.sa_bo = NULL; |
265 | p->const_ib.semaphore = NULL; |
- | |
266 | p->chunk_ib_idx = -1; |
274 | p->chunk_ib = NULL; |
267 | p->chunk_relocs_idx = -1; |
275 | p->chunk_relocs = NULL; |
268 | p->chunk_flags_idx = -1; |
276 | p->chunk_flags = NULL; |
269 | p->chunk_const_ib_idx = -1; |
277 | p->chunk_const_ib = NULL; |
270 | p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); |
278 | p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); |
271 | if (p->chunks_array == NULL) { |
279 | if (p->chunks_array == NULL) { |
272 | return -ENOMEM; |
280 | return -ENOMEM; |
273 | } |
281 | } |
274 | chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); |
282 | chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); |
Line 291... | Line 299... | ||
291 | if (copy_from_user(&user_chunk, chunk_ptr, |
299 | if (copy_from_user(&user_chunk, chunk_ptr, |
292 | sizeof(struct drm_radeon_cs_chunk))) { |
300 | sizeof(struct drm_radeon_cs_chunk))) { |
293 | return -EFAULT; |
301 | return -EFAULT; |
294 | } |
302 | } |
295 | p->chunks[i].length_dw = user_chunk.length_dw; |
303 | p->chunks[i].length_dw = user_chunk.length_dw; |
296 | p->chunks[i].chunk_id = user_chunk.chunk_id; |
- | |
297 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { |
304 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_RELOCS) { |
298 | p->chunk_relocs_idx = i; |
305 | p->chunk_relocs = &p->chunks[i]; |
299 | } |
306 | } |
300 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) { |
307 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_IB) { |
301 | p->chunk_ib_idx = i; |
308 | p->chunk_ib = &p->chunks[i]; |
302 | /* zero length IB isn't useful */ |
309 | /* zero length IB isn't useful */ |
303 | if (p->chunks[i].length_dw == 0) |
310 | if (p->chunks[i].length_dw == 0) |
304 | return -EINVAL; |
311 | return -EINVAL; |
305 | } |
312 | } |
306 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) { |
313 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_CONST_IB) { |
307 | p->chunk_const_ib_idx = i; |
314 | p->chunk_const_ib = &p->chunks[i]; |
308 | /* zero length CONST IB isn't useful */ |
315 | /* zero length CONST IB isn't useful */ |
309 | if (p->chunks[i].length_dw == 0) |
316 | if (p->chunks[i].length_dw == 0) |
310 | return -EINVAL; |
317 | return -EINVAL; |
311 | } |
318 | } |
312 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { |
319 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_FLAGS) { |
313 | p->chunk_flags_idx = i; |
320 | p->chunk_flags = &p->chunks[i]; |
314 | /* zero length flags aren't useful */ |
321 | /* zero length flags aren't useful */ |
315 | if (p->chunks[i].length_dw == 0) |
322 | if (p->chunks[i].length_dw == 0) |
316 | return -EINVAL; |
323 | return -EINVAL; |
317 | } |
324 | } |
Line 318... | Line 325... | ||
318 | 325 | ||
319 | size = p->chunks[i].length_dw; |
326 | size = p->chunks[i].length_dw; |
320 | cdata = (void __user *)(unsigned long)user_chunk.chunk_data; |
327 | cdata = (void __user *)(unsigned long)user_chunk.chunk_data; |
321 | p->chunks[i].user_ptr = cdata; |
328 | p->chunks[i].user_ptr = cdata; |
322 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) |
329 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_CONST_IB) |
Line 323... | Line 330... | ||
323 | continue; |
330 | continue; |
324 | 331 | ||
325 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) { |
332 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_IB) { |
326 | if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP)) |
333 | if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP)) |
Line 327... | Line 334... | ||
327 | continue; |
334 | continue; |
Line 333... | Line 340... | ||
333 | return -ENOMEM; |
340 | return -ENOMEM; |
334 | } |
341 | } |
335 | if (copy_from_user(p->chunks[i].kdata, cdata, size)) { |
342 | if (copy_from_user(p->chunks[i].kdata, cdata, size)) { |
336 | return -EFAULT; |
343 | return -EFAULT; |
337 | } |
344 | } |
338 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { |
345 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_FLAGS) { |
339 | p->cs_flags = p->chunks[i].kdata[0]; |
346 | p->cs_flags = p->chunks[i].kdata[0]; |
340 | if (p->chunks[i].length_dw > 1) |
347 | if (p->chunks[i].length_dw > 1) |
341 | ring = p->chunks[i].kdata[1]; |
348 | ring = p->chunks[i].kdata[1]; |
342 | if (p->chunks[i].length_dw > 2) |
349 | if (p->chunks[i].length_dw > 2) |
343 | priority = (s32)p->chunks[i].kdata[2]; |
350 | priority = (s32)p->chunks[i].kdata[2]; |
Line 374... | Line 381... | ||
374 | } |
381 | } |
Line 375... | Line 382... | ||
375 | 382 | ||
376 | static int cmp_size_smaller_first(void *priv, struct list_head *a, |
383 | static int cmp_size_smaller_first(void *priv, struct list_head *a, |
377 | struct list_head *b) |
384 | struct list_head *b) |
378 | { |
385 | { |
379 | struct radeon_cs_reloc *la = list_entry(a, struct radeon_cs_reloc, tv.head); |
386 | struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, tv.head); |
Line 380... | Line 387... | ||
380 | struct radeon_cs_reloc *lb = list_entry(b, struct radeon_cs_reloc, tv.head); |
387 | struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, tv.head); |
381 | 388 | ||
382 | /* Sort A before B if A is smaller. */ |
389 | /* Sort A before B if A is smaller. */ |
Line 408... | Line 415... | ||
408 | */ |
415 | */ |
409 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); |
416 | list_sort(NULL, &parser->validated, cmp_size_smaller_first); |
Line 410... | Line 417... | ||
410 | 417 | ||
411 | ttm_eu_fence_buffer_objects(&parser->ticket, |
418 | ttm_eu_fence_buffer_objects(&parser->ticket, |
412 | &parser->validated, |
419 | &parser->validated, |
413 | parser->ib.fence); |
420 | &parser->ib.fence->base); |
414 | } else if (backoff) { |
421 | } else if (backoff) { |
415 | ttm_eu_backoff_reservation(&parser->ticket, |
422 | ttm_eu_backoff_reservation(&parser->ticket, |
416 | &parser->validated); |
423 | &parser->validated); |
Line 417... | Line 424... | ||
417 | } |
424 | } |
418 | 425 | ||
419 | if (parser->relocs != NULL) { |
426 | if (parser->relocs != NULL) { |
- | 427 | for (i = 0; i < parser->nrelocs; i++) { |
|
- | 428 | struct radeon_bo *bo = parser->relocs[i].robj; |
|
- | 429 | if (bo == NULL) |
|
420 | for (i = 0; i < parser->nrelocs; i++) { |
430 | continue; |
421 | if (parser->relocs[i].gobj) |
431 | |
422 | drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); |
432 | drm_gem_object_unreference_unlocked(&bo->gem_base); |
423 | } |
433 | } |
424 | } |
434 | } |
425 | kfree(parser->track); |
- | |
426 | kfree(parser->relocs); |
435 | kfree(parser->track); |
427 | kfree(parser->relocs_ptr); |
436 | kfree(parser->relocs); |
428 | kfree(parser->vm_bos); |
437 | drm_free_large(parser->vm_bos); |
429 | for (i = 0; i < parser->nchunks; i++) |
438 | for (i = 0; i < parser->nchunks; i++) |
430 | drm_free_large(parser->chunks[i].kdata); |
439 | drm_free_large(parser->chunks[i].kdata); |
431 | kfree(parser->chunks); |
440 | kfree(parser->chunks); |
Line 437... | Line 446... | ||
437 | static int radeon_cs_ib_chunk(struct radeon_device *rdev, |
446 | static int radeon_cs_ib_chunk(struct radeon_device *rdev, |
438 | struct radeon_cs_parser *parser) |
447 | struct radeon_cs_parser *parser) |
439 | { |
448 | { |
440 | int r; |
449 | int r; |
Line 441... | Line 450... | ||
441 | 450 | ||
442 | if (parser->chunk_ib_idx == -1) |
451 | if (parser->chunk_ib == NULL) |
Line 443... | Line 452... | ||
443 | return 0; |
452 | return 0; |
444 | 453 | ||
Line 449... | Line 458... | ||
449 | if (r || parser->parser_error) { |
458 | if (r || parser->parser_error) { |
450 | DRM_ERROR("Invalid command stream !\n"); |
459 | DRM_ERROR("Invalid command stream !\n"); |
451 | return r; |
460 | return r; |
452 | } |
461 | } |
Line -... | Line 462... | ||
- | 462 | ||
- | 463 | r = radeon_cs_sync_rings(parser); |
|
- | 464 | if (r) { |
|
- | 465 | if (r != -ERESTARTSYS) |
|
- | 466 | DRM_ERROR("Failed to sync rings: %i\n", r); |
|
- | 467 | return r; |
|
- | 468 | } |
|
453 | 469 | ||
454 | if (parser->ring == R600_RING_TYPE_UVD_INDEX) |
470 | if (parser->ring == R600_RING_TYPE_UVD_INDEX) |
455 | radeon_uvd_note_usage(rdev); |
471 | radeon_uvd_note_usage(rdev); |
456 | else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) || |
472 | else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) || |
457 | (parser->ring == TN_RING_TYPE_VCE2_INDEX)) |
473 | (parser->ring == TN_RING_TYPE_VCE2_INDEX)) |
Line 458... | Line -... | ||
458 | radeon_vce_note_usage(rdev); |
- | |
459 | 474 | radeon_vce_note_usage(rdev); |
|
460 | radeon_cs_sync_rings(parser); |
475 | |
461 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
476 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
462 | if (r) { |
477 | if (r) { |
463 | DRM_ERROR("Failed to schedule IB !\n"); |
478 | DRM_ERROR("Failed to schedule IB !\n"); |
Line 491... | Line 506... | ||
491 | return r; |
506 | return r; |
Line 492... | Line 507... | ||
492 | 507 | ||
493 | for (i = 0; i < p->nrelocs; i++) { |
508 | for (i = 0; i < p->nrelocs; i++) { |
Line 494... | Line -... | ||
494 | struct radeon_bo *bo; |
- | |
495 | - | ||
496 | /* ignore duplicates */ |
- | |
497 | if (p->relocs_ptr[i] != &p->relocs[i]) |
- | |
498 | continue; |
509 | struct radeon_bo *bo; |
499 | 510 | ||
500 | bo = p->relocs[i].robj; |
511 | bo = p->relocs[i].robj; |
501 | bo_va = radeon_vm_bo_find(vm, bo); |
512 | bo_va = radeon_vm_bo_find(vm, bo); |
502 | if (bo_va == NULL) { |
513 | if (bo_va == NULL) { |
503 | dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm); |
514 | dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm); |
Line 504... | Line 515... | ||
504 | return -EINVAL; |
515 | return -EINVAL; |
505 | } |
516 | } |
506 | 517 | ||
- | 518 | r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem); |
|
- | 519 | if (r) |
|
507 | r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem); |
520 | return r; |
Line 508... | Line 521... | ||
508 | if (r) |
521 | |
509 | return r; |
522 | radeon_sync_fence(&p->ib.sync, bo_va->last_pt_update); |
Line 517... | Line 530... | ||
517 | { |
530 | { |
518 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; |
531 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; |
519 | struct radeon_vm *vm = &fpriv->vm; |
532 | struct radeon_vm *vm = &fpriv->vm; |
520 | int r; |
533 | int r; |
Line 521... | Line 534... | ||
521 | 534 | ||
522 | if (parser->chunk_ib_idx == -1) |
535 | if (parser->chunk_ib == NULL) |
523 | return 0; |
536 | return 0; |
524 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
537 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
Line 525... | Line 538... | ||
525 | return 0; |
538 | return 0; |
Line 542... | Line 555... | ||
542 | mutex_lock(&vm->mutex); |
555 | mutex_lock(&vm->mutex); |
543 | r = radeon_bo_vm_update_pte(parser, vm); |
556 | r = radeon_bo_vm_update_pte(parser, vm); |
544 | if (r) { |
557 | if (r) { |
545 | goto out; |
558 | goto out; |
546 | } |
559 | } |
- | 560 | ||
547 | radeon_cs_sync_rings(parser); |
561 | r = radeon_cs_sync_rings(parser); |
- | 562 | if (r) { |
|
- | 563 | if (r != -ERESTARTSYS) |
|
548 | radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence); |
564 | DRM_ERROR("Failed to sync rings: %i\n", r); |
- | 565 | goto out; |
|
- | 566 | } |
|
Line 549... | Line 567... | ||
549 | 567 | ||
550 | if ((rdev->family >= CHIP_TAHITI) && |
568 | if ((rdev->family >= CHIP_TAHITI) && |
551 | (parser->chunk_const_ib_idx != -1)) { |
569 | (parser->chunk_const_ib != NULL)) { |
552 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true); |
570 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true); |
553 | } else { |
571 | } else { |
554 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
572 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
Line 573... | Line 591... | ||
573 | { |
591 | { |
574 | struct radeon_cs_chunk *ib_chunk; |
592 | struct radeon_cs_chunk *ib_chunk; |
575 | struct radeon_vm *vm = NULL; |
593 | struct radeon_vm *vm = NULL; |
576 | int r; |
594 | int r; |
Line 577... | Line 595... | ||
577 | 595 | ||
578 | if (parser->chunk_ib_idx == -1) |
596 | if (parser->chunk_ib == NULL) |
Line 579... | Line 597... | ||
579 | return 0; |
597 | return 0; |
580 | 598 | ||
581 | if (parser->cs_flags & RADEON_CS_USE_VM) { |
599 | if (parser->cs_flags & RADEON_CS_USE_VM) { |
Line 582... | Line 600... | ||
582 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; |
600 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; |
583 | vm = &fpriv->vm; |
601 | vm = &fpriv->vm; |
584 | 602 | ||
585 | if ((rdev->family >= CHIP_TAHITI) && |
603 | if ((rdev->family >= CHIP_TAHITI) && |
586 | (parser->chunk_const_ib_idx != -1)) { |
604 | (parser->chunk_const_ib != NULL)) { |
587 | ib_chunk = &parser->chunks[parser->chunk_const_ib_idx]; |
605 | ib_chunk = parser->chunk_const_ib; |
588 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
606 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
589 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); |
607 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); |
Line 601... | Line 619... | ||
601 | ib_chunk->user_ptr, |
619 | ib_chunk->user_ptr, |
602 | ib_chunk->length_dw * 4)) |
620 | ib_chunk->length_dw * 4)) |
603 | return -EFAULT; |
621 | return -EFAULT; |
604 | } |
622 | } |
Line 605... | Line 623... | ||
605 | 623 | ||
606 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; |
624 | ib_chunk = parser->chunk_ib; |
607 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
625 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
608 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); |
626 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); |
609 | return -EINVAL; |
627 | return -EINVAL; |
610 | } |
628 | } |
611 | } |
629 | } |
Line 612... | Line 630... | ||
612 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; |
630 | ib_chunk = parser->chunk_ib; |
613 | 631 | ||
614 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, |
632 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, |
615 | vm, ib_chunk->length_dw * 4); |
633 | vm, ib_chunk->length_dw * 4); |
Line 692... | Line 710... | ||
692 | **/ |
710 | **/ |
693 | int radeon_cs_packet_parse(struct radeon_cs_parser *p, |
711 | int radeon_cs_packet_parse(struct radeon_cs_parser *p, |
694 | struct radeon_cs_packet *pkt, |
712 | struct radeon_cs_packet *pkt, |
695 | unsigned idx) |
713 | unsigned idx) |
696 | { |
714 | { |
697 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; |
715 | struct radeon_cs_chunk *ib_chunk = p->chunk_ib; |
698 | struct radeon_device *rdev = p->rdev; |
716 | struct radeon_device *rdev = p->rdev; |
699 | uint32_t header; |
717 | uint32_t header; |
Line 700... | Line 718... | ||
700 | 718 | ||
701 | if (idx >= ib_chunk->length_dw) { |
719 | if (idx >= ib_chunk->length_dw) { |
Line 786... | Line 804... | ||
786 | * |
804 | * |
787 | * Check if next packet is relocation packet3, do bo validation and compute |
805 | * Check if next packet is relocation packet3, do bo validation and compute |
788 | * GPU offset using the provided start. |
806 | * GPU offset using the provided start. |
789 | **/ |
807 | **/ |
790 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, |
808 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, |
791 | struct radeon_cs_reloc **cs_reloc, |
809 | struct radeon_bo_list **cs_reloc, |
792 | int nomm) |
810 | int nomm) |
793 | { |
811 | { |
794 | struct radeon_cs_chunk *relocs_chunk; |
812 | struct radeon_cs_chunk *relocs_chunk; |
795 | struct radeon_cs_packet p3reloc; |
813 | struct radeon_cs_packet p3reloc; |
796 | unsigned idx; |
814 | unsigned idx; |
797 | int r; |
815 | int r; |
Line 798... | Line 816... | ||
798 | 816 | ||
799 | if (p->chunk_relocs_idx == -1) { |
817 | if (p->chunk_relocs == NULL) { |
800 | DRM_ERROR("No relocation chunk !\n"); |
818 | DRM_ERROR("No relocation chunk !\n"); |
801 | return -EINVAL; |
819 | return -EINVAL; |
802 | } |
820 | } |
803 | *cs_reloc = NULL; |
821 | *cs_reloc = NULL; |
804 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
822 | relocs_chunk = p->chunk_relocs; |
805 | r = radeon_cs_packet_parse(p, &p3reloc, p->idx); |
823 | r = radeon_cs_packet_parse(p, &p3reloc, p->idx); |
806 | if (r) |
824 | if (r) |
807 | return r; |
825 | return r; |
808 | p->idx += p3reloc.count + 2; |
826 | p->idx += p3reloc.count + 2; |
Line 825... | Line 843... | ||
825 | *cs_reloc = p->relocs; |
843 | *cs_reloc = p->relocs; |
826 | (*cs_reloc)->gpu_offset = |
844 | (*cs_reloc)->gpu_offset = |
827 | (u64)relocs_chunk->kdata[idx + 3] << 32; |
845 | (u64)relocs_chunk->kdata[idx + 3] << 32; |
828 | (*cs_reloc)->gpu_offset |= relocs_chunk->kdata[idx + 0]; |
846 | (*cs_reloc)->gpu_offset |= relocs_chunk->kdata[idx + 0]; |
829 | } else |
847 | } else |
830 | *cs_reloc = p->relocs_ptr[(idx / 4)]; |
848 | *cs_reloc = &p->relocs[(idx / 4)]; |
831 | return 0; |
849 | return 0; |
832 | }><>=>>>>>>>>>>> |
850 | }><>=>>>>>>>>> |