[Intel-gfx] [PATCH v3 12/14] drm/i915/guc: Preemption! With GuC

Chris Wilson chris at chris-wilson.co.uk
Fri Oct 20 09:00:35 UTC 2017


Quoting MichaƂ Winiarski (2017-10-19 19:36:17)
> @@ -686,10 +802,23 @@ static void i915_guc_irq_handler(unsigned long data)
>         struct intel_engine_cs * const engine = (struct intel_engine_cs *)data;
>         struct intel_engine_execlists * const execlists = &engine->execlists;
>         struct execlist_port *port = execlists->port;
> -       const struct execlist_port * const last_port =
> -               &execlists->port[execlists->port_mask];
>         struct drm_i915_gem_request *rq;
>  
> +       if (READ_ONCE(execlists->preempt) &&
> +           intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) ==
> +           GUC_PREEMPT_FINISHED) {
> +               execlists_cancel_port_requests(&engine->execlists);
> +
> +               spin_lock_irq(&engine->timeline->lock);
> +               execlists_unwind_incomplete_requests(execlists);
> +               spin_unlock_irq(&engine->timeline->lock);
> +
> +               wait_for_guc_preempt_report(engine);
> +
> +               WRITE_ONCE(execlists->preempt, false);
> +               intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0);
> +       }
> +
>         rq = port_request(&port[0]);
>         while (rq && i915_gem_request_completed(rq)) {
>                 trace_i915_gem_request_out(rq);
> @@ -701,7 +830,7 @@ static void i915_guc_irq_handler(unsigned long data)
>                 rq = port_request(&port[0]);
>         }
>  
> -       if (!port_isset(last_port))
> +       if (!READ_ONCE(execlists->preempt))
>                 i915_guc_dequeue(engine);
>  }

    kworker/u9:1-1687  [000] d..1  2215.658429: inject_preempt_context: GUC WQ tail=330, head=320
    kworker/u9:1-1687  [000] d..1  2215.658429: inject_preempt_context: RING tail=1a0
    kworker/u9:1-1687  [000] ....  2215.658429: inject_preempt_context: PREEMPT: WQI ADDED ring=2, guc_id=1
    kworker/u9:1-1687  [000] ....  2215.658429: inject_preempt_context: PREEMPT: GUC ACTION SENDING ring=2, guc_id=1
          <idle>-0     [003] d.h1  2215.658456: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [003] ..s1  2215.658460: i915_guc_irq_handler: PREEMPT: WAITING FOR GUC COMPLETE ring=2, guc_id=1
          <idle>-0     [000] d.h1  2215.658462: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [003] ..s1  2215.658473: i915_guc_irq_handler: PREEMPT: FINISHED ring=2, guc_id=1
          <idle>-0     [003] d.s2  2215.658473: i915_gem_request_execute: dev=0, ring=2, ctx=2983, seqno=6, global=0
          <idle>-0     [003] d.s2  2215.658476: i915_gem_request_in: dev=0, ring=2, ctx=2983, seqno=6, global=916, port=0
          <idle>-0     [003] d.s2  2215.658476: i915_gem_request_execute: dev=0, ring=2, ctx=3298, seqno=6, global=0
          <idle>-0     [003] d.s2  2215.658477: i915_gem_request_in: dev=0, ring=2, ctx=3298, seqno=6, global=917, port=1
          <idle>-0     [002] d.h1  2215.658510: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [000] d.h1  2215.658517: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [002] ..s1  2215.658520: i915_gem_request_out: dev=0, ring=2, ctx=2983, seqno=6, global=916
          <idle>-0     [002] ..s1  2215.658521: i915_gem_request_out: dev=0, ring=2, ctx=3298, seqno=6, global=917
          <idle>-0     [002] d.s2  2215.658521: i915_gem_request_execute: dev=0, ring=2, ctx=3323, seqno=5, global=0
          <idle>-0     [002] d.s2  2215.658522: i915_gem_request_in: dev=0, ring=2, ctx=3323, seqno=5, global=918, port=0
          <idle>-0     [002] d.s2  2215.658523: i915_gem_request_execute: dev=0, ring=2, ctx=3363, seqno=4, global=0
          <idle>-0     [002] d.s2  2215.658524: i915_gem_request_in: dev=0, ring=2, ctx=3363, seqno=4, global=919, port=1
          <idle>-0     [002] d.h1  2215.658569: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [002] ..s1  2215.658572: i915_gem_request_out: dev=0, ring=2, ctx=3323, seqno=5, global=918
          <idle>-0     [002] ..s1  2215.658572: i915_gem_request_out: dev=0, ring=2, ctx=3363, seqno=4, global=919
          <idle>-0     [002] d.s2  2215.658573: i915_gem_request_execute: dev=0, ring=2, ctx=3673, seqno=2, global=0
          <idle>-0     [000] d.h1  2215.658574: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [002] d.s2  2215.658576: i915_gem_request_in: dev=0, ring=2, ctx=3673, seqno=2, global=920, port=0
          <idle>-0     [002] d.s2  2215.658576: i915_gem_request_execute: dev=0, ring=2, ctx=2783, seqno=3, global=0
          <idle>-0     [002] d.s2  2215.658578: i915_gem_request_in: dev=0, ring=2, ctx=2783, seqno=3, global=921, port=1
     ksoftirqd/0-7     [000] d.H2  2215.658587: i915_gem_request_submit: dev=0, ring=2, ctx=3003, seqno=3, global=0
     ksoftirqd/0-7     [000] d.s1  2215.658591: i915_guc_irq_handler: PREEMPT: WORKER QUEUED ring=2, guc_id=1
          <idle>-0     [002] d.h1  2215.658649: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [000] d.h1  2215.658656: gen8_cs_irq_handler: USER INTERRUPT ring=2, guc_id=1
          <idle>-0     [002] ..s1  2215.658659: i915_guc_irq_handler: PREEMPT: IN PROGRESS, NOT DONE ring=2, guc_id=1
          <idle>-0     [002] ..s1  2215.658659: i915_gem_request_out: dev=0, ring=2, ctx=3673, seqno=2, global=920
          <idle>-0     [002] ..s1  2215.658660: i915_gem_request_out: dev=0, ring=2, ctx=2783, seqno=3, global=921
          <idle>-0     [001] d.h2  2215.658663: i915_gem_request_submit: dev=0, ring=2, ctx=4013, seqno=6, global=0
          <idle>-0     [002] dNh2  2215.658725: i915_gem_request_submit: dev=0, ring=2, ctx=2928, seqno=6, global=0
    kworker/u9:1-1687  [000] d..1  2215.660436: inject_preempt_context: GUC WQ tail=340, head=330
    kworker/u9:1-1687  [000] d..1  2215.660436: inject_preempt_context: RING tail=1c0
    kworker/u9:1-1687  [000] ....  2215.660437: inject_preempt_context: PREEMPT: WQI ADDED ring=2, guc_id=1
    kworker/u9:1-1687  [000] ....  2215.660437: inject_preempt_context: PREEMPT: GUC ACTION SENDING ring=2, guc_id=1

This suggests that the decision to queue the preempt-worker is racy, and
not evidence that the USER_INTERRUPT went missing. Do you have a better
example?
-Chris


More information about the Intel-gfx mailing list