Skip to content

Commit 507d977

Browse files
committed
drm/i915: Pass vma to relocate entry
We can simplify our tracking of pending writes in an execbuf to the single bit in the vma->exec_entry->flags, but that requires the relocation function knowing the object's vma. Pass it along. Note we have only been using a single bit to track flushing since commit cc889e0 Author: Daniel Vetter <[email protected]> Date: Wed Jun 13 20:45:19 2012 +0200 drm/i915: disable flushing_list/gpu_write_list unconditionally flushed all render caches before the breadcrumb and commit 6ac42f4 Author: Daniel Vetter <[email protected]> Date: Sat Jul 21 12:25:01 2012 +0200 drm/i915: Replace the complex flushing logic with simple invalidate/flush all did away with the explicit GPU domain tracking. This was then codified into the ABI with NO_RELOC in commit ed5982e Author: Daniel Vetter <[email protected]> # Oi! Patch stealer! Date: Thu Jan 17 22:23:36 2013 +0100 drm/i915: Allow userspace to hint that the relocations were known Signed-off-by: Chris Wilson <[email protected]> Reviewed-by: Joonas Lahtinen <[email protected]>
1 parent 4ff4b44 commit 507d977

File tree

1 file changed

+42
-60
lines changed

1 file changed

+42
-60
lines changed

drivers/gpu/drm/i915/i915_gem_execbuffer.c

Lines changed: 42 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -622,42 +622,25 @@ relocate_entry(struct drm_i915_gem_object *obj,
622622
}
623623

624624
static int
625-
eb_relocate_entry(struct drm_i915_gem_object *obj,
625+
eb_relocate_entry(struct i915_vma *vma,
626626
struct i915_execbuffer *eb,
627627
struct drm_i915_gem_relocation_entry *reloc)
628628
{
629-
struct drm_gem_object *target_obj;
630-
struct drm_i915_gem_object *target_i915_obj;
631-
struct i915_vma *target_vma;
632-
uint64_t target_offset;
629+
struct i915_vma *target;
630+
u64 target_offset;
633631
int ret;
634632

635633
/* we've already hold a reference to all valid objects */
636-
target_vma = eb_get_vma(eb, reloc->target_handle);
637-
if (unlikely(target_vma == NULL))
634+
target = eb_get_vma(eb, reloc->target_handle);
635+
if (unlikely(!target))
638636
return -ENOENT;
639-
target_i915_obj = target_vma->obj;
640-
target_obj = &target_vma->obj->base;
641-
642-
target_offset = gen8_canonical_addr(target_vma->node.start);
643-
644-
/* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
645-
* pipe_control writes because the gpu doesn't properly redirect them
646-
* through the ppgtt for non_secure batchbuffers. */
647-
if (unlikely(IS_GEN6(eb->i915) &&
648-
reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION)) {
649-
ret = i915_vma_bind(target_vma, target_i915_obj->cache_level,
650-
PIN_GLOBAL);
651-
if (WARN_ONCE(ret, "Unexpected failure to bind target VMA!"))
652-
return ret;
653-
}
654637

655638
/* Validate that the target is in a valid r/w GPU domain */
656639
if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
657640
DRM_DEBUG("reloc with multiple write domains: "
658-
"obj %p target %d offset %d "
641+
"target %d offset %d "
659642
"read %08x write %08x",
660-
obj, reloc->target_handle,
643+
reloc->target_handle,
661644
(int) reloc->offset,
662645
reloc->read_domains,
663646
reloc->write_domain);
@@ -666,43 +649,57 @@ eb_relocate_entry(struct drm_i915_gem_object *obj,
666649
if (unlikely((reloc->write_domain | reloc->read_domains)
667650
& ~I915_GEM_GPU_DOMAINS)) {
668651
DRM_DEBUG("reloc with read/write non-GPU domains: "
669-
"obj %p target %d offset %d "
652+
"target %d offset %d "
670653
"read %08x write %08x",
671-
obj, reloc->target_handle,
654+
reloc->target_handle,
672655
(int) reloc->offset,
673656
reloc->read_domains,
674657
reloc->write_domain);
675658
return -EINVAL;
676659
}
677660

678-
target_obj->pending_read_domains |= reloc->read_domains;
679-
target_obj->pending_write_domain |= reloc->write_domain;
661+
if (reloc->write_domain)
662+
target->exec_entry->flags |= EXEC_OBJECT_WRITE;
663+
664+
/*
665+
* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
666+
* pipe_control writes because the gpu doesn't properly redirect them
667+
* through the ppgtt for non_secure batchbuffers.
668+
*/
669+
if (unlikely(IS_GEN6(eb->i915) &&
670+
reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION)) {
671+
ret = i915_vma_bind(target, target->obj->cache_level,
672+
PIN_GLOBAL);
673+
if (WARN_ONCE(ret, "Unexpected failure to bind target VMA!"))
674+
return ret;
675+
}
680676

681677
/* If the relocation already has the right value in it, no
682678
* more work needs to be done.
683679
*/
680+
target_offset = gen8_canonical_addr(target->node.start);
684681
if (target_offset == reloc->presumed_offset)
685682
return 0;
686683

687684
/* Check that the relocation address is valid... */
688685
if (unlikely(reloc->offset >
689-
obj->base.size - (eb->reloc_cache.use_64bit_reloc ? 8 : 4))) {
686+
vma->size - (eb->reloc_cache.use_64bit_reloc ? 8 : 4))) {
690687
DRM_DEBUG("Relocation beyond object bounds: "
691-
"obj %p target %d offset %d size %d.\n",
692-
obj, reloc->target_handle,
693-
(int) reloc->offset,
694-
(int) obj->base.size);
688+
"target %d offset %d size %d.\n",
689+
reloc->target_handle,
690+
(int)reloc->offset,
691+
(int)vma->size);
695692
return -EINVAL;
696693
}
697694
if (unlikely(reloc->offset & 3)) {
698695
DRM_DEBUG("Relocation not 4-byte aligned: "
699-
"obj %p target %d offset %d.\n",
700-
obj, reloc->target_handle,
701-
(int) reloc->offset);
696+
"target %d offset %d.\n",
697+
reloc->target_handle,
698+
(int)reloc->offset);
702699
return -EINVAL;
703700
}
704701

705-
ret = relocate_entry(obj, reloc, &eb->reloc_cache, target_offset);
702+
ret = relocate_entry(vma->obj, reloc, &eb->reloc_cache, target_offset);
706703
if (ret)
707704
return ret;
708705

@@ -748,7 +745,7 @@ static int eb_relocate_vma(struct i915_vma *vma, struct i915_execbuffer *eb)
748745
do {
749746
u64 offset = r->presumed_offset;
750747

751-
ret = eb_relocate_entry(vma->obj, eb, r);
748+
ret = eb_relocate_entry(vma, eb, r);
752749
if (ret)
753750
goto out;
754751

@@ -794,7 +791,7 @@ eb_relocate_vma_slow(struct i915_vma *vma,
794791
int i, ret = 0;
795792

796793
for (i = 0; i < entry->relocation_count; i++) {
797-
ret = eb_relocate_entry(vma->obj, eb, &relocs[i]);
794+
ret = eb_relocate_entry(vma, eb, &relocs[i]);
798795
if (ret)
799796
break;
800797
}
@@ -827,7 +824,6 @@ eb_reserve_vma(struct i915_vma *vma,
827824
struct intel_engine_cs *engine,
828825
bool *need_reloc)
829826
{
830-
struct drm_i915_gem_object *obj = vma->obj;
831827
struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
832828
uint64_t flags;
833829
int ret;
@@ -881,11 +877,6 @@ eb_reserve_vma(struct i915_vma *vma,
881877
*need_reloc = true;
882878
}
883879

884-
if (entry->flags & EXEC_OBJECT_WRITE) {
885-
obj->base.pending_read_domains = I915_GEM_DOMAIN_RENDER;
886-
obj->base.pending_write_domain = I915_GEM_DOMAIN_RENDER;
887-
}
888-
889880
return 0;
890881
}
891882

@@ -948,7 +939,6 @@ static int eb_reserve(struct i915_execbuffer *eb)
948939
{
949940
const bool has_fenced_gpu_access = INTEL_GEN(eb->i915) < 4;
950941
const bool needs_unfenced_map = INTEL_INFO(eb->i915)->unfenced_needs_alignment;
951-
struct drm_i915_gem_object *obj;
952942
struct i915_vma *vma;
953943
struct list_head ordered_vmas;
954944
struct list_head pinned_vmas;
@@ -961,7 +951,6 @@ static int eb_reserve(struct i915_execbuffer *eb)
961951
bool need_fence, need_mappable;
962952

963953
vma = list_first_entry(&eb->vmas, struct i915_vma, exec_link);
964-
obj = vma->obj;
965954
entry = vma->exec_entry;
966955

967956
if (eb->ctx->flags & CONTEXT_NO_ZEROMAP)
@@ -982,9 +971,6 @@ static int eb_reserve(struct i915_execbuffer *eb)
982971
list_move(&vma->exec_link, &ordered_vmas);
983972
} else
984973
list_move_tail(&vma->exec_link, &ordered_vmas);
985-
986-
obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND;
987-
obj->base.pending_write_domain = 0;
988974
}
989975
list_splice(&ordered_vmas, &eb->vmas);
990976
list_splice(&pinned_vmas, &eb->vmas);
@@ -1170,7 +1156,7 @@ eb_move_to_gpu(struct i915_execbuffer *eb)
11701156
i915_gem_clflush_object(obj, 0);
11711157

11721158
ret = i915_gem_request_await_object
1173-
(eb->request, obj, obj->base.pending_write_domain);
1159+
(eb->request, obj, vma->exec_entry->flags & EXEC_OBJECT_WRITE);
11741160
if (ret)
11751161
return ret;
11761162
}
@@ -1366,12 +1352,10 @@ eb_move_to_active(struct i915_execbuffer *eb)
13661352
list_for_each_entry(vma, &eb->vmas, exec_link) {
13671353
struct drm_i915_gem_object *obj = vma->obj;
13681354

1369-
obj->base.write_domain = obj->base.pending_write_domain;
1370-
if (obj->base.write_domain)
1371-
vma->exec_entry->flags |= EXEC_OBJECT_WRITE;
1372-
else
1373-
obj->base.pending_read_domains |= obj->base.read_domains;
1374-
obj->base.read_domains = obj->base.pending_read_domains;
1355+
obj->base.write_domain = 0;
1356+
if (vma->exec_entry->flags & EXEC_OBJECT_WRITE)
1357+
obj->base.read_domains = 0;
1358+
obj->base.read_domains |= I915_GEM_GPU_DOMAINS;
13751359

13761360
i915_vma_move_to_active(vma, eb->request, vma->exec_entry->flags);
13771361
eb_export_fence(obj, eb->request, vma->exec_entry->flags);
@@ -1681,8 +1665,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
16811665
goto err;
16821666
}
16831667

1684-
/* Set the pending read domains for the batch buffer to COMMAND */
1685-
if (eb.batch->obj->base.pending_write_domain) {
1668+
if (eb.batch->exec_entry->flags & EXEC_OBJECT_WRITE) {
16861669
DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
16871670
ret = -EINVAL;
16881671
goto err;
@@ -1719,7 +1702,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
17191702
}
17201703
}
17211704

1722-
eb.batch->obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND;
17231705
if (eb.batch_len == 0)
17241706
eb.batch_len = eb.batch->size - eb.batch_start_offset;
17251707

0 commit comments

Comments
 (0)