Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6937 | Rev 7144 | ||
---|---|---|---|
Line 191... | Line 191... | ||
191 | if (handle >= -eb->and) |
191 | if (handle >= -eb->and) |
192 | return NULL; |
192 | return NULL; |
193 | return eb->lut[handle]; |
193 | return eb->lut[handle]; |
194 | } else { |
194 | } else { |
195 | struct hlist_head *head; |
195 | struct hlist_head *head; |
196 | struct hlist_node *node; |
- | |
197 | - | ||
198 | head = &eb->buckets[handle & eb->and]; |
- | |
199 | hlist_for_each(node, head) { |
- | |
200 | struct i915_vma *vma; |
196 | struct i915_vma *vma; |
Line -... | Line 197... | ||
- | 197 | ||
201 | 198 | head = &eb->buckets[handle & eb->and]; |
|
202 | vma = hlist_entry(node, struct i915_vma, exec_node); |
199 | hlist_for_each_entry(vma, head, exec_node) { |
203 | if (vma->exec_handle == handle) |
200 | if (vma->exec_handle == handle) |
204 | return vma; |
201 | return vma; |
205 | } |
202 | } |
206 | return NULL; |
203 | return NULL; |
Line 331... | Line 328... | ||
331 | return ret; |
328 | return ret; |
Line 332... | Line 329... | ||
332 | 329 | ||
333 | /* Map the page containing the relocation we're going to perform. */ |
330 | /* Map the page containing the relocation we're going to perform. */ |
334 | offset = i915_gem_obj_ggtt_offset(obj); |
331 | offset = i915_gem_obj_ggtt_offset(obj); |
335 | offset += reloc->offset; |
332 | offset += reloc->offset; |
336 | MapPage(dev_priv->gtt.mappable,dev_priv->gtt.mappable_base + |
333 | reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, |
337 | (offset & PAGE_MASK), PG_SW); |
- | |
338 | reloc_page = dev_priv->gtt.mappable; |
334 | offset & PAGE_MASK); |
Line -... | Line 335... | ||
- | 335 | iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset)); |
|
- | 336 | ||
- | 337 | if (INTEL_INFO(dev)->gen >= 8) { |
|
- | 338 | offset += sizeof(uint32_t); |
|
339 | iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset)); |
339 | |
- | 340 | if (offset_in_page(offset) == 0) { |
|
- | 341 | io_mapping_unmap_atomic(reloc_page); |
|
- | 342 | reloc_page = |
|
- | 343 | io_mapping_map_atomic_wc(dev_priv->gtt.mappable, |
|
- | 344 | offset); |
|
- | 345 | } |
|
- | 346 | ||
- | 347 | iowrite32(upper_32_bits(delta), |
|
- | 348 | reloc_page + offset_in_page(offset)); |
|
- | 349 | } |
|
Line 340... | Line 350... | ||
340 | 350 | ||
341 | // io_mapping_unmap_atomic(reloc_page); |
351 | io_mapping_unmap_atomic(reloc_page); |
Line 342... | Line 352... | ||
342 | 352 | ||
Line 510... | Line 520... | ||
510 | int count = remain; |
520 | int count = remain; |
511 | if (count > ARRAY_SIZE(stack_reloc)) |
521 | if (count > ARRAY_SIZE(stack_reloc)) |
512 | count = ARRAY_SIZE(stack_reloc); |
522 | count = ARRAY_SIZE(stack_reloc); |
513 | remain -= count; |
523 | remain -= count; |
Line 514... | Line 524... | ||
514 | 524 | ||
- | 525 | if (__copy_from_user_inatomic(r, user_relocs, count*sizeof(r[0]))) |
|
Line 515... | Line 526... | ||
515 | memcpy(r, user_relocs, count*sizeof(r[0])); |
526 | return -EFAULT; |
516 | 527 | ||
Line 517... | Line 528... | ||
517 | do { |
528 | do { |
518 | u64 offset = r->presumed_offset; |
529 | u64 offset = r->presumed_offset; |
519 | 530 | ||
Line 520... | Line 531... | ||
520 | ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r); |
531 | ret = i915_gem_execbuffer_relocate_entry(vma->obj, eb, r); |
521 | if (ret) |
- | |
522 | return ret; |
532 | if (ret) |
523 | 533 | return ret; |
|
524 | if (r->presumed_offset != offset) |
534 | |
- | 535 | if (r->presumed_offset != offset && |
|
525 | { |
536 | __copy_to_user_inatomic(&user_relocs->presumed_offset, |
Line 526... | Line 537... | ||
526 | memcpy(&user_relocs->presumed_offset, |
537 | &r->presumed_offset, |
527 | &r->presumed_offset, |
538 | sizeof(r->presumed_offset))) { |
528 | sizeof(r->presumed_offset)); |
539 | return -EFAULT; |
Line 653... | Line 664... | ||
653 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
664 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
Line 654... | Line 665... | ||
654 | 665 | ||
655 | if (entry->relocation_count == 0) |
666 | if (entry->relocation_count == 0) |
Line 656... | Line 667... | ||
656 | return false; |
667 | return false; |
657 | 668 | ||
Line 658... | Line 669... | ||
658 | if (!i915_is_ggtt(vma->vm)) |
669 | if (!vma->is_ggtt) |
659 | return false; |
670 | return false; |
660 | 671 | ||
Line 672... | Line 683... | ||
672 | eb_vma_misplaced(struct i915_vma *vma) |
683 | eb_vma_misplaced(struct i915_vma *vma) |
673 | { |
684 | { |
674 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
685 | struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; |
675 | struct drm_i915_gem_object *obj = vma->obj; |
686 | struct drm_i915_gem_object *obj = vma->obj; |
Line 676... | Line 687... | ||
676 | 687 | ||
677 | WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && |
- | |
Line 678... | Line 688... | ||
678 | !i915_is_ggtt(vma->vm)); |
688 | WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && !vma->is_ggtt); |
679 | 689 | ||
680 | if (entry->alignment && |
690 | if (entry->alignment && |
Line 1284... | Line 1294... | ||
1284 | 1294 | ||
1285 | exec_len = args->batch_len; |
1295 | exec_len = args->batch_len; |
1286 | exec_start = params->batch_obj_vm_offset + |
1296 | exec_start = params->batch_obj_vm_offset + |
Line -... | Line 1297... | ||
- | 1297 | params->args_batch_start_offset; |
|
- | 1298 | ||
- | 1299 | if (exec_len == 0) |
|
1287 | params->args_batch_start_offset; |
1300 | exec_len = params->batch_obj->base.size; |
1288 | 1301 | ||
1289 | ret = ring->dispatch_execbuffer(params->request, |
1302 | ret = ring->dispatch_execbuffer(params->request, |
1290 | exec_start, exec_len, |
1303 | exec_start, exec_len, |
1291 | params->dispatch_flags); |
1304 | params->dispatch_flags); |
Line 1300... | Line 1313... | ||
1300 | return 0; |
1313 | return 0; |
1301 | } |
1314 | } |
Line 1302... | Line 1315... | ||
1302 | 1315 | ||
1303 | /** |
1316 | /** |
1304 | * Find one BSD ring to dispatch the corresponding BSD command. |
1317 | * Find one BSD ring to dispatch the corresponding BSD command. |
1305 | * The Ring ID is returned. |
1318 | * The ring index is returned. |
1306 | */ |
1319 | */ |
1307 | static int gen8_dispatch_bsd_ring(struct drm_device *dev, |
1320 | static unsigned int |
1308 | struct drm_file *file) |
1321 | gen8_dispatch_bsd_ring(struct drm_i915_private *dev_priv, struct drm_file *file) |
1309 | { |
- | |
1310 | struct drm_i915_private *dev_priv = dev->dev_private; |
1322 | { |
Line 1311... | Line 1323... | ||
1311 | struct drm_i915_file_private *file_priv = file->driver_priv; |
1323 | struct drm_i915_file_private *file_priv = file->driver_priv; |
1312 | 1324 | ||
1313 | /* Check whether the file_priv is using one ring */ |
- | |
1314 | if (file_priv->bsd_ring) |
- | |
1315 | return file_priv->bsd_ring->id; |
1325 | /* Check whether the file_priv has already selected one ring. */ |
1316 | else { |
- | |
1317 | /* If no, use the ping-pong mechanism to select one ring */ |
- | |
1318 | int ring_id; |
1326 | if ((int)file_priv->bsd_ring < 0) { |
1319 | 1327 | /* If not, use the ping-pong mechanism to select one. */ |
|
1320 | mutex_lock(&dev->struct_mutex); |
- | |
1321 | if (dev_priv->mm.bsd_ring_dispatch_index == 0) { |
1328 | mutex_lock(&dev_priv->dev->struct_mutex); |
1322 | ring_id = VCS; |
- | |
1323 | dev_priv->mm.bsd_ring_dispatch_index = 1; |
- | |
1324 | } else { |
- | |
1325 | ring_id = VCS2; |
- | |
1326 | dev_priv->mm.bsd_ring_dispatch_index = 0; |
- | |
1327 | } |
1329 | file_priv->bsd_ring = dev_priv->mm.bsd_ring_dispatch_index; |
1328 | file_priv->bsd_ring = &dev_priv->ring[ring_id]; |
- | |
1329 | mutex_unlock(&dev->struct_mutex); |
1330 | dev_priv->mm.bsd_ring_dispatch_index ^= 1; |
- | 1331 | mutex_unlock(&dev_priv->dev->struct_mutex); |
|
- | 1332 | } |
|
1330 | return ring_id; |
1333 | |
Line 1331... | Line 1334... | ||
1331 | } |
1334 | return file_priv->bsd_ring; |
1332 | } |
1335 | } |
1333 | 1336 | ||
Line 1349... | Line 1352... | ||
1349 | vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; |
1352 | vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; |
Line 1350... | Line 1353... | ||
1350 | 1353 | ||
1351 | return vma->obj; |
1354 | return vma->obj; |
Line -... | Line 1355... | ||
- | 1355 | } |
|
- | 1356 | ||
- | 1357 | #define I915_USER_RINGS (4) |
|
- | 1358 | ||
- | 1359 | static const enum intel_ring_id user_ring_map[I915_USER_RINGS + 1] = { |
|
- | 1360 | [I915_EXEC_DEFAULT] = RCS, |
|
- | 1361 | [I915_EXEC_RENDER] = RCS, |
|
- | 1362 | [I915_EXEC_BLT] = BCS, |
|
- | 1363 | [I915_EXEC_BSD] = VCS, |
|
- | 1364 | [I915_EXEC_VEBOX] = VECS |
|
- | 1365 | }; |
|
- | 1366 | ||
- | 1367 | static int |
|
- | 1368 | eb_select_ring(struct drm_i915_private *dev_priv, |
|
- | 1369 | struct drm_file *file, |
|
- | 1370 | struct drm_i915_gem_execbuffer2 *args, |
|
- | 1371 | struct intel_engine_cs **ring) |
|
- | 1372 | { |
|
- | 1373 | unsigned int user_ring_id = args->flags & I915_EXEC_RING_MASK; |
|
- | 1374 | ||
- | 1375 | if (user_ring_id > I915_USER_RINGS) { |
|
- | 1376 | DRM_DEBUG("execbuf with unknown ring: %u\n", user_ring_id); |
|
- | 1377 | return -EINVAL; |
|
- | 1378 | } |
|
- | 1379 | ||
- | 1380 | if ((user_ring_id != I915_EXEC_BSD) && |
|
- | 1381 | ((args->flags & I915_EXEC_BSD_MASK) != 0)) { |
|
- | 1382 | DRM_DEBUG("execbuf with non bsd ring but with invalid " |
|
- | 1383 | "bsd dispatch flags: %d\n", (int)(args->flags)); |
|
- | 1384 | return -EINVAL; |
|
- | 1385 | } |
|
- | 1386 | ||
- | 1387 | if (user_ring_id == I915_EXEC_BSD && HAS_BSD2(dev_priv)) { |
|
- | 1388 | unsigned int bsd_idx = args->flags & I915_EXEC_BSD_MASK; |
|
- | 1389 | ||
- | 1390 | if (bsd_idx == I915_EXEC_BSD_DEFAULT) { |
|
- | 1391 | bsd_idx = gen8_dispatch_bsd_ring(dev_priv, file); |
|
- | 1392 | } else if (bsd_idx >= I915_EXEC_BSD_RING1 && |
|
- | 1393 | bsd_idx <= I915_EXEC_BSD_RING2) { |
|
- | 1394 | bsd_idx >>= I915_EXEC_BSD_SHIFT; |
|
- | 1395 | bsd_idx--; |
|
- | 1396 | } else { |
|
- | 1397 | DRM_DEBUG("execbuf with unknown bsd ring: %u\n", |
|
- | 1398 | bsd_idx); |
|
- | 1399 | return -EINVAL; |
|
- | 1400 | } |
|
- | 1401 | ||
- | 1402 | *ring = &dev_priv->ring[_VCS(bsd_idx)]; |
|
- | 1403 | } else { |
|
- | 1404 | *ring = &dev_priv->ring[user_ring_map[user_ring_id]]; |
|
- | 1405 | } |
|
- | 1406 | ||
- | 1407 | if (!intel_ring_initialized(*ring)) { |
|
- | 1408 | DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id); |
|
- | 1409 | return -EINVAL; |
|
- | 1410 | } |
|
- | 1411 | ||
- | 1412 | return 0; |
|
1352 | } |
1413 | } |
1353 | 1414 | ||
1354 | static int |
1415 | static int |
1355 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, |
1416 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, |
1356 | struct drm_file *file, |
1417 | struct drm_file *file, |
1357 | struct drm_i915_gem_execbuffer2 *args, |
1418 | struct drm_i915_gem_execbuffer2 *args, |
1358 | struct drm_i915_gem_exec_object2 *exec) |
1419 | struct drm_i915_gem_exec_object2 *exec) |
- | 1420 | { |
|
1359 | { |
1421 | struct drm_i915_private *dev_priv = dev->dev_private; |
1360 | struct drm_i915_private *dev_priv = dev->dev_private; |
1422 | struct drm_i915_gem_request *req = NULL; |
1361 | struct eb_vmas *eb; |
1423 | struct eb_vmas *eb; |
1362 | struct drm_i915_gem_object *batch_obj; |
1424 | struct drm_i915_gem_object *batch_obj; |
1363 | struct drm_i915_gem_exec_object2 shadow_exec_entry; |
1425 | struct drm_i915_gem_exec_object2 shadow_exec_entry; |
Line 1384... | Line 1446... | ||
1384 | dispatch_flags |= I915_DISPATCH_SECURE; |
1446 | dispatch_flags |= I915_DISPATCH_SECURE; |
1385 | } |
1447 | } |
1386 | if (args->flags & I915_EXEC_IS_PINNED) |
1448 | if (args->flags & I915_EXEC_IS_PINNED) |
1387 | dispatch_flags |= I915_DISPATCH_PINNED; |
1449 | dispatch_flags |= I915_DISPATCH_PINNED; |
Line 1388... | Line -... | ||
1388 | - | ||
1389 | if ((args->flags & I915_EXEC_RING_MASK) > LAST_USER_RING) { |
- | |
1390 | DRM_DEBUG("execbuf with unknown ring: %d\n", |
- | |
1391 | (int)(args->flags & I915_EXEC_RING_MASK)); |
- | |
1392 | return -EINVAL; |
- | |
1393 | } |
- | |
1394 | - | ||
1395 | if (((args->flags & I915_EXEC_RING_MASK) != I915_EXEC_BSD) && |
- | |
1396 | ((args->flags & I915_EXEC_BSD_MASK) != 0)) { |
- | |
1397 | DRM_DEBUG("execbuf with non bsd ring but with invalid " |
1450 | |
1398 | "bsd dispatch flags: %d\n", (int)(args->flags)); |
- | |
1399 | return -EINVAL; |
- | |
1400 | } |
- | |
1401 | - | ||
1402 | if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT) |
- | |
1403 | ring = &dev_priv->ring[RCS]; |
- | |
1404 | else if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_BSD) { |
- | |
1405 | if (HAS_BSD2(dev)) { |
- | |
1406 | int ring_id; |
- | |
1407 | - | ||
1408 | switch (args->flags & I915_EXEC_BSD_MASK) { |
- | |
1409 | case I915_EXEC_BSD_DEFAULT: |
- | |
1410 | ring_id = gen8_dispatch_bsd_ring(dev, file); |
- | |
1411 | ring = &dev_priv->ring[ring_id]; |
- | |
1412 | break; |
- | |
1413 | case I915_EXEC_BSD_RING1: |
- | |
1414 | ring = &dev_priv->ring[VCS]; |
- | |
1415 | break; |
- | |
1416 | case I915_EXEC_BSD_RING2: |
- | |
1417 | ring = &dev_priv->ring[VCS2]; |
1451 | ret = eb_select_ring(dev_priv, file, args, &ring); |
1418 | break; |
- | |
1419 | default: |
- | |
1420 | DRM_DEBUG("execbuf with unknown bsd ring: %d\n", |
- | |
1421 | (int)(args->flags & I915_EXEC_BSD_MASK)); |
- | |
1422 | return -EINVAL; |
- | |
1423 | } |
- | |
1424 | } else |
- | |
1425 | ring = &dev_priv->ring[VCS]; |
- | |
1426 | } else |
- | |
1427 | ring = &dev_priv->ring[(args->flags & I915_EXEC_RING_MASK) - 1]; |
- | |
1428 | - | ||
1429 | if (!intel_ring_initialized(ring)) { |
- | |
1430 | DRM_DEBUG("execbuf with invalid ring: %d\n", |
- | |
1431 | (int)(args->flags & I915_EXEC_RING_MASK)); |
1452 | if (ret) |
1432 | return -EINVAL; |
- | |
Line 1433... | Line 1453... | ||
1433 | } |
1453 | return ret; |
1434 | 1454 | ||
1435 | if (args->buffer_count < 1) { |
1455 | if (args->buffer_count < 1) { |
1436 | DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); |
1456 | DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); |
Line 1578... | Line 1598... | ||
1578 | params->batch_obj_vm_offset = i915_gem_obj_ggtt_offset(batch_obj); |
1598 | params->batch_obj_vm_offset = i915_gem_obj_ggtt_offset(batch_obj); |
1579 | } else |
1599 | } else |
1580 | params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm); |
1600 | params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm); |
Line 1581... | Line 1601... | ||
1581 | 1601 | ||
1582 | /* Allocate a request for this batch buffer nice and early. */ |
1602 | /* Allocate a request for this batch buffer nice and early. */ |
1583 | ret = i915_gem_request_alloc(ring, ctx, ¶ms->request); |
1603 | req = i915_gem_request_alloc(ring, ctx); |
- | 1604 | if (IS_ERR(req)) { |
|
1584 | if (ret) |
1605 | ret = PTR_ERR(req); |
- | 1606 | goto err_batch_unpin; |
|
Line 1585... | Line 1607... | ||
1585 | goto err_batch_unpin; |
1607 | } |
1586 | 1608 | ||
1587 | ret = i915_gem_request_add_to_client(params->request, file); |
1609 | ret = i915_gem_request_add_to_client(req, file); |
Line 1588... | Line 1610... | ||
1588 | if (ret) |
1610 | if (ret) |
1589 | goto err_batch_unpin; |
1611 | goto err_batch_unpin; |
Line 1598... | Line 1620... | ||
1598 | params->file = file; |
1620 | params->file = file; |
1599 | params->ring = ring; |
1621 | params->ring = ring; |
1600 | params->dispatch_flags = dispatch_flags; |
1622 | params->dispatch_flags = dispatch_flags; |
1601 | params->batch_obj = batch_obj; |
1623 | params->batch_obj = batch_obj; |
1602 | params->ctx = ctx; |
1624 | params->ctx = ctx; |
- | 1625 | params->request = req; |
|
Line 1603... | Line 1626... | ||
1603 | 1626 | ||
Line 1604... | Line 1627... | ||
1604 | ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas); |
1627 | ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas); |
1605 | 1628 | ||
Line 1621... | Line 1644... | ||
1621 | /* |
1644 | /* |
1622 | * If the request was created but not successfully submitted then it |
1645 | * If the request was created but not successfully submitted then it |
1623 | * must be freed again. If it was submitted then it is being tracked |
1646 | * must be freed again. If it was submitted then it is being tracked |
1624 | * on the active request list and no clean up is required here. |
1647 | * on the active request list and no clean up is required here. |
1625 | */ |
1648 | */ |
1626 | if (ret && params->request) |
1649 | if (ret && !IS_ERR_OR_NULL(req)) |
1627 | i915_gem_request_cancel(params->request); |
1650 | i915_gem_request_cancel(req); |
Line 1628... | Line 1651... | ||
1628 | 1651 | ||
Line 1629... | Line 1652... | ||
1629 | mutex_unlock(&dev->struct_mutex); |
1652 | mutex_unlock(&dev->struct_mutex); |
1630 | 1653 |