diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2019-01-25 05:05:20 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2019-01-25 06:19:39 -0500 |
commit | e1a73a54a96e80dc6009e73c9209e4f81ae22285 (patch) | |
tree | cadd51eb146190119e6fcd60916b77a2accc96a3 /drivers/gpu/drm/i915/intel_engine_cs.c | |
parent | 8e525cb4a622148fbe30134ee3a1a34ad839a43a (diff) |
drm/i915: Measure the required reserved size for request emission
Instead of tediously and fragilely counting up the number of dwords
required to emit the breadcrumb to seal a request, fake a request and
measure it automatically once during engine setup.
The downside is that this requires a fair amount of mocking to create a
proper breadcrumb. Still, should be less error prone in future as the
breadcrumb size fluctuates!
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190125100520.20163-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/intel_engine_cs.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_engine_cs.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 2f3c71f6d313..8f738a7cd117 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c | |||
@@ -604,6 +604,47 @@ static void __intel_context_unpin(struct i915_gem_context *ctx, | |||
604 | intel_context_unpin(to_intel_context(ctx, engine)); | 604 | intel_context_unpin(to_intel_context(ctx, engine)); |
605 | } | 605 | } |
606 | 606 | ||
607 | struct measure_breadcrumb { | ||
608 | struct i915_request rq; | ||
609 | struct i915_timeline timeline; | ||
610 | struct intel_ring ring; | ||
611 | u32 cs[1024]; | ||
612 | }; | ||
613 | |||
614 | static int measure_breadcrumb_sz(struct intel_engine_cs *engine) | ||
615 | { | ||
616 | struct measure_breadcrumb *frame; | ||
617 | unsigned int dw; | ||
618 | |||
619 | GEM_BUG_ON(!engine->i915->gt.scratch); | ||
620 | |||
621 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); | ||
622 | if (!frame) | ||
623 | return -ENOMEM; | ||
624 | |||
625 | i915_timeline_init(engine->i915, &frame->timeline, "measure"); | ||
626 | |||
627 | INIT_LIST_HEAD(&frame->ring.request_list); | ||
628 | frame->ring.timeline = &frame->timeline; | ||
629 | frame->ring.vaddr = frame->cs; | ||
630 | frame->ring.size = sizeof(frame->cs); | ||
631 | frame->ring.effective_size = frame->ring.size; | ||
632 | intel_ring_update_space(&frame->ring); | ||
633 | |||
634 | frame->rq.i915 = engine->i915; | ||
635 | frame->rq.engine = engine; | ||
636 | frame->rq.ring = &frame->ring; | ||
637 | frame->rq.timeline = &frame->timeline; | ||
638 | |||
639 | dw = engine->emit_breadcrumb(&frame->rq, frame->cs) - frame->cs; | ||
640 | GEM_BUG_ON(dw != engine->emit_breadcrumb_sz); | ||
641 | |||
642 | i915_timeline_fini(&frame->timeline); | ||
643 | kfree(frame); | ||
644 | |||
645 | return dw; | ||
646 | } | ||
647 | |||
607 | /** | 648 | /** |
608 | * intel_engines_init_common - initialize cengine state which might require hw access | 649 | * intel_engines_init_common - initialize cengine state which might require hw access |
609 | * @engine: Engine to initialize. | 650 | * @engine: Engine to initialize. |
@@ -657,8 +698,16 @@ int intel_engine_init_common(struct intel_engine_cs *engine) | |||
657 | if (ret) | 698 | if (ret) |
658 | goto err_breadcrumbs; | 699 | goto err_breadcrumbs; |
659 | 700 | ||
701 | ret = measure_breadcrumb_sz(engine); | ||
702 | if (ret < 0) | ||
703 | goto err_status_page; | ||
704 | |||
705 | engine->emit_breadcrumb_sz = ret; | ||
706 | |||
660 | return 0; | 707 | return 0; |
661 | 708 | ||
709 | err_status_page: | ||
710 | cleanup_status_page(engine); | ||
662 | err_breadcrumbs: | 711 | err_breadcrumbs: |
663 | intel_engine_fini_breadcrumbs(engine); | 712 | intel_engine_fini_breadcrumbs(engine); |
664 | err_unpin_preempt: | 713 | err_unpin_preempt: |