From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Cc: Eero Tamminen <eero.t.tamminen@intel.com>
Subject: Re: [PATCH 1/6] drm/i915: Limit C-states when waiting for the active request
Date: Mon, 6 Aug 2018 10:34:54 +0100 [thread overview]
Message-ID: <aef4d5bb-425d-58cf-bd14-e19a491981a3@linux.intel.com> (raw)
In-Reply-To: <20180806083017.32215-1-chris@chris-wilson.co.uk>
On 06/08/2018 09:30, Chris Wilson wrote:
> If we are waiting for the currently executing request, we have a good
> idea that it will be completed in the very near future and so want to
> cap the CPU_DMA_LATENCY to ensure that we wake up the client quickly.
I cannot shake the opinion that we shouldn't be doing this. For instance
what if the client has been re-niced (down), or it has re-niced itself?
Obviously wrong to apply this for those.
Or when you say we have a good idea something will be completed in the
very near future. Say there is a 60fps workload which is sending 5ms
batches and waits on them. That would be 30% of time spent outside of
low C states for a workload which doesn't need it.
Also having read what the OpenCL does, where they want to apply
different wait optimisations for different call-sites, the idea that we
should instead be introducing a low-latency flag to wait ioctl sounds
more appropriate.
>
> v2: Not allowed to block in kmalloc after setting TASK_INTERRUPTIBLE.
> v3: Avoid the blocking notifier as well for TASK_INTERRUPTIBLE
> v4: Beautification?
> v5: And ignore the preemptibility of queue_work before schedule.
> v6: Use highpri wq to keep our pm_qos window as small as possible.
>
> Testcase: igt/gem_sync/store-default
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Eero Tamminen <eero.t.tamminen@intel.com>
> Cc: Francisco Jerez <currojerez@riseup.net>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Cc: Dmitry Rogozhkin <dmitry.v.rogozhkin@intel.com>
> ---
> drivers/gpu/drm/i915/i915_request.c | 59 +++++++++++++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index 5c2c93cbab12..67fd2ec75d78 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -1258,6 +1258,58 @@ static bool __i915_wait_request_check_and_reset(struct i915_request *request)
> return true;
> }
>
> +struct wait_dma_qos {
> + struct pm_qos_request req;
> + struct work_struct add, del;
> +};
> +
> +static void __wait_dma_qos_add(struct work_struct *work)
> +{
> + struct wait_dma_qos *qos = container_of(work, typeof(*qos), add);
> +
> + pm_qos_add_request(&qos->req, PM_QOS_CPU_DMA_LATENCY, 50);
> +}
> +
> +static void __wait_dma_qos_del(struct work_struct *work)
> +{
> + struct wait_dma_qos *qos = container_of(work, typeof(*qos), del);
> +
> + if (!cancel_work_sync(&qos->add))
> + pm_qos_remove_request(&qos->req);
> +
> + kfree(qos);
> +}
> +
> +static struct wait_dma_qos *wait_dma_qos_add(void)
> +{
> + struct wait_dma_qos *qos;
> +
> + /* Called under TASK_INTERRUPTIBLE, so not allowed to sleep/block. */
> + qos = kzalloc(sizeof(*qos), GFP_NOWAIT | __GFP_NOWARN);
> + if (!qos)
> + return NULL;
> +
> + INIT_WORK(&qos->add, __wait_dma_qos_add);
> + INIT_WORK(&qos->del, __wait_dma_qos_del);
> +
> + /*
> + * Schedule the enabling work on the local cpu so that it should only
> + * take effect if we actually sleep. If schedule() short circuits due to
> + * our request already being completed, we should then be able to cancel
> + * the work before it is even run.
> + */
> + queue_work_on(raw_smp_processor_id(), system_highpri_wq, &qos->add);
> +
> + return qos;
> +}
> +
> +static void wait_dma_qos_del(struct wait_dma_qos *qos)
> +{
> + /* Defer to worker so not incur extra latency for our woken client. */
> + if (qos)
> + queue_work(system_highpri_wq, &qos->del);
> +}
> +
> /**
> * i915_request_wait - wait until execution of request has finished
> * @rq: the request to wait upon
> @@ -1286,6 +1338,7 @@ long i915_request_wait(struct i915_request *rq,
> wait_queue_head_t *errq = &rq->i915->gpu_error.wait_queue;
> DEFINE_WAIT_FUNC(reset, default_wake_function);
> DEFINE_WAIT_FUNC(exec, default_wake_function);
> + struct wait_dma_qos *qos = NULL;
> struct intel_wait wait;
>
> might_sleep();
> @@ -1363,6 +1416,11 @@ long i915_request_wait(struct i915_request *rq,
> break;
> }
>
> + if (!qos &&
> + i915_seqno_passed(intel_engine_get_seqno(rq->engine),
> + wait.seqno - 1))
I also realized that this will get incorrectly applied when there is
preemption. If a low-priority request gets preempted after we applied
the PM QoS it will persist for much longer than intended. (Until the
high-prio request completes and then low-prio one.) And the explicit
low-latency wait flag would have the same problem. We could perhaps go
with removing the PM QoS request if preempted. It should not be frequent
enough to cause issue with too much traffic on the API. But
Another side note - quick grep shows there are a few other "seqno - 1"
callsites so perhaps we should add a helper for this with a more
self-explanatory like __i915_seqno_is_executing(engine, seqno) or something?
> + qos = wait_dma_qos_add();
> +
> timeout = io_schedule_timeout(timeout);
>
> if (intel_wait_complete(&wait) &&
> @@ -1412,6 +1470,7 @@ long i915_request_wait(struct i915_request *rq,
> if (flags & I915_WAIT_LOCKED)
> remove_wait_queue(errq, &reset);
> remove_wait_queue(&rq->execute, &exec);
> + wait_dma_qos_del(qos);
> trace_i915_request_wait_end(rq);
>
> return timeout;
>
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-08-06 9:34 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-06 8:30 [PATCH 1/6] drm/i915: Limit C-states when waiting for the active request Chris Wilson
2018-08-06 8:30 ` [PATCH 2/6] drm/i915: Reserve some priority bits for internal use Chris Wilson
2018-08-06 8:30 ` [PATCH 3/6] drm/i915: Combine multiple internal plists into the same i915_priolist bucket Chris Wilson
2018-08-06 8:30 ` [PATCH 4/6] drm/i915: Priority boost for new clients Chris Wilson
2018-08-06 9:47 ` Tvrtko Ursulin
2018-08-07 7:29 ` [PATCH v2] " Chris Wilson
2018-08-07 9:08 ` Tvrtko Ursulin
2018-08-07 15:02 ` Chris Wilson
2018-08-08 12:40 ` Tvrtko Ursulin
2018-08-08 18:53 ` Chris Wilson
2018-08-08 19:24 ` Chris Wilson
2018-08-06 8:30 ` [PATCH 5/6] drm/i915: Pull scheduling under standalone lock Chris Wilson
2018-08-06 8:30 ` [PATCH 6/6] drm/i915: Priority boost for waiting clients Chris Wilson
2018-08-06 9:53 ` Tvrtko Ursulin
2018-08-06 10:03 ` Chris Wilson
2018-08-06 10:30 ` Tvrtko Ursulin
2018-08-06 8:41 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] drm/i915: Limit C-states when waiting for the active request Patchwork
2018-08-06 8:44 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-08-06 8:56 ` ✓ Fi.CI.BAT: success " Patchwork
2018-08-06 9:34 ` Tvrtko Ursulin [this message]
2018-08-06 9:59 ` [PATCH 1/6] " Chris Wilson
2018-08-06 10:28 ` Tvrtko Ursulin
2018-08-06 9:43 ` ✗ Fi.CI.IGT: failure for series starting with [1/6] " Patchwork
2018-08-07 7:33 ` ✗ Fi.CI.BAT: failure for series starting with [1/6] drm/i915: Limit C-states when waiting for the active request (rev2) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aef4d5bb-425d-58cf-bd14-e19a491981a3@linux.intel.com \
--to=tvrtko.ursulin@linux.intel.com \
--cc=chris@chris-wilson.co.uk \
--cc=eero.t.tamminen@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.