From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 34/40] drm/i915: Allow contexts to share a single timeline across all engines
Date: Tue, 25 Sep 2018 09:45:17 +0100 [thread overview]
Message-ID: <b029d409-233b-d464-8d2a-40032881d159@linux.intel.com> (raw)
In-Reply-To: <20180919195544.1511-34-chris@chris-wilson.co.uk>
On 19/09/2018 20:55, Chris Wilson wrote:
> Previously, our view has been always to run the engines independently
> within a context. (Multiple engines happened before we had contexts and
> timelines, so they always operated independently and that behaviour
> persisted into contexts.) However, at the user level the context often
> represents a single timeline (e.g. GL contexts) and userspace must
> ensure that the individual engines are serialised to present that
> ordering to the client (or forgot about this detail entirely and hope no
> one notices - a fair ploy if the client can only directly control one
> engine themselves ;)
>
> In the next patch, we will want to construct a set of engines that
> operate as one, that have a single timeline interwoven between them, to
> present a single virtual engine to the user. (They submit to the virtual
> engine, then we decide which engine to execute on based.)
>
> To that end, we want to be able to create contexts which have a single
> timeline (fence context) shared between all engines, rather than multiple
> timelines.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/i915_gem_context.c | 26 ++++++++++++++++-
> drivers/gpu/drm/i915/i915_gem_context.h | 3 ++
> drivers/gpu/drm/i915/i915_request.c | 10 +++++--
> drivers/gpu/drm/i915/i915_request.h | 5 +++-
> drivers/gpu/drm/i915/i915_sw_fence.c | 39 +++++++++++++++++++++----
> drivers/gpu/drm/i915/i915_sw_fence.h | 13 +++++++--
> drivers/gpu/drm/i915/intel_lrc.c | 5 +++-
> include/uapi/drm/i915_drm.h | 3 +-
> 8 files changed, 91 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index da2ac10f8e8a..a8570a07b3b7 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -223,6 +223,9 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
> ce->ops->destroy(ce);
> }
>
> + if (ctx->timeline)
> + i915_timeline_put(ctx->timeline);
> +
> kfree(ctx->name);
> put_pid(ctx->pid);
>
> @@ -402,6 +405,7 @@ static void __destroy_hw_context(struct i915_gem_context *ctx,
> }
>
> #define CREATE_VM BIT(0)
> +#define CREATE_TIMELINE BIT(1)
>
> static struct i915_gem_context *
> i915_gem_create_context(struct drm_i915_private *dev_priv,
> @@ -412,6 +416,9 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
>
> lockdep_assert_held(&dev_priv->drm.struct_mutex);
>
> + if (flags & CREATE_TIMELINE && !HAS_EXECLISTS(dev_priv))
> + return ERR_PTR(-EINVAL);
> +
> /* Reap the most stale context */
> contexts_free_first(dev_priv);
>
> @@ -434,6 +441,18 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
> ctx->desc_template = default_desc_template(dev_priv, ppgtt);
> }
>
> + if (flags & CREATE_TIMELINE) {
> + struct i915_timeline *timeline;
> +
> + timeline = i915_timeline_create(dev_priv, ctx->name);
> + if (IS_ERR(timeline)) {
> + __destroy_hw_context(ctx, file_priv);
> + return ERR_CAST(timeline);
> + }
> +
> + ctx->timeline = timeline;
> + }
> +
> trace_i915_context_create(ctx);
>
> return ctx;
> @@ -796,7 +815,9 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
> if (args->pad != 0)
> return -EINVAL;
>
> - if (args->flags & ~I915_GEM_CONTEXT_SHARE_GTT)
> + if (args->flags &
> + ~(I915_GEM_CONTEXT_SHARE_GTT |
> + I915_GEM_CONTEXT_SINGLE_TIMELINE))
> return -EINVAL;
>
> if (client_is_banned(file_priv)) {
> @@ -820,6 +841,9 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
> flags &= ~CREATE_VM;
> }
>
> + if (args->flags & I915_GEM_CONTEXT_SINGLE_TIMELINE)
> + flags |= CREATE_TIMELINE;
> +
> err = i915_mutex_lock_interruptible(dev);
> if (err)
> goto out;
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
> index 08165f6a0a84..770043449ba6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.h
> +++ b/drivers/gpu/drm/i915/i915_gem_context.h
> @@ -41,6 +41,7 @@ struct drm_i915_private;
> struct drm_i915_file_private;
> struct i915_hw_ppgtt;
> struct i915_request;
> +struct i915_timeline;
> struct i915_vma;
> struct intel_ring;
>
> @@ -66,6 +67,8 @@ struct i915_gem_context {
> /** file_priv: owning file descriptor */
> struct drm_i915_file_private *file_priv;
>
> + struct i915_timeline *timeline;
Put a short comment please.
> +
> /**
> * @ppgtt: unique address space (GTT)
> *
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index fc7ad8dbc36e..34d410cfa577 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -1007,8 +1007,14 @@ void i915_request_add(struct i915_request *request)
> prev = i915_gem_active_raw(&timeline->last_request,
> &request->i915->drm.struct_mutex);
> if (prev && !i915_request_completed(prev)) {
> - i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
> - &request->submitq);
> + if (prev->engine == engine)
> + i915_sw_fence_await_sw_fence(&request->submit,
> + &prev->submit,
> + &request->submitq);
> + else
> + __i915_sw_fence_await_dma_fence(&request->submit,
> + &prev->fence,
> + &request->dmaq);
Could be worth a comment on the conditional block to help future readers.
> if (engine->schedule)
> __i915_sched_node_add_dependency(&request->sched,
> &prev->sched,
> diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
> index 90e9d170a0cd..68d36eeb5edb 100644
> --- a/drivers/gpu/drm/i915/i915_request.h
> +++ b/drivers/gpu/drm/i915/i915_request.h
> @@ -116,7 +116,10 @@ struct i915_request {
> * It is used by the driver to then queue the request for execution.
> */
> struct i915_sw_fence submit;
> - wait_queue_entry_t submitq;
> + union {
> + wait_queue_entry_t submitq;
> + struct i915_sw_dma_fence_cb dmaq;
Drop a comment here as well explaining the duality.
> + };
> wait_queue_head_t execute;
>
> /*
> diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
> index 6dbeed079ae5..b68883fe73c5 100644
> --- a/drivers/gpu/drm/i915/i915_sw_fence.c
> +++ b/drivers/gpu/drm/i915/i915_sw_fence.c
> @@ -362,11 +362,6 @@ int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
> return __i915_sw_fence_await_sw_fence(fence, signaler, NULL, gfp);
> }
>
> -struct i915_sw_dma_fence_cb {
> - struct dma_fence_cb base;
> - struct i915_sw_fence *fence;
> -};
> -
> struct i915_sw_dma_fence_cb_timer {
> struct i915_sw_dma_fence_cb base;
> struct dma_fence *dma;
> @@ -483,6 +478,40 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
> return ret;
> }
>
> +static void __dma_i915_sw_fence_wake(struct dma_fence *dma,
> + struct dma_fence_cb *data)
> +{
> + struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
> +
> + i915_sw_fence_complete(cb->fence);
> +}
> +
> +int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
> + struct dma_fence *dma,
> + struct i915_sw_dma_fence_cb *cb)
> +{
> + int ret;
> +
> + debug_fence_assert(fence);
> +
> + if (dma_fence_is_signaled(dma))
> + return 0;
> +
> + cb->fence = fence;
> + i915_sw_fence_await(fence);
> +
> + ret = dma_fence_add_callback(dma, &cb->base, __dma_i915_sw_fence_wake);
> + if (ret == 0) {
> + ret = 1;
> + } else {
> + i915_sw_fence_complete(fence);
> + if (ret == -ENOENT) /* fence already signaled */
> + ret = 0;
> + }
> +
> + return ret;
> +}
ACAICS there is scope to extract commonality between this and
i915_sw_fence_await_dma_fence by perhaps having a common static function
which takes the _cb and func pointers. Or something like:
static __i915_sw_fence_await_dma_fence(..., *cb, *func)
{
...
}
i915_sw_fence_await_dma_fence(..)
{
... alloc ..
__i915_sw_fence_await_dma_fence(..., cb, i915_sw_fence_await);
...
}
i915_sw_fence_await_dma_fence_builtin(...)
{
_i915_sw_fence_await_dma_fence(..., &dma->cb, __dma_i915_sw_fence_wake);
}
Thoughts?
Regards,
Tvrtko
> +
> int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
> struct reservation_object *resv,
> const struct dma_fence_ops *exclude,
> diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h b/drivers/gpu/drm/i915/i915_sw_fence.h
> index fe2ef4dadfc6..914a734d49bc 100644
> --- a/drivers/gpu/drm/i915/i915_sw_fence.h
> +++ b/drivers/gpu/drm/i915/i915_sw_fence.h
> @@ -10,14 +10,13 @@
> #ifndef _I915_SW_FENCE_H_
> #define _I915_SW_FENCE_H_
>
> +#include <linux/dma-fence.h>
> #include <linux/gfp.h>
> #include <linux/kref.h>
> #include <linux/notifier.h> /* for NOTIFY_DONE */
> #include <linux/wait.h>
>
> struct completion;
> -struct dma_fence;
> -struct dma_fence_ops;
> struct reservation_object;
>
> struct i915_sw_fence {
> @@ -69,10 +68,20 @@ int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
> int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
> struct i915_sw_fence *after,
> gfp_t gfp);
> +
> +struct i915_sw_dma_fence_cb {
> + struct dma_fence_cb base;
> + struct i915_sw_fence *fence;
> +};
> +
> +int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
> + struct dma_fence *dma,
> + struct i915_sw_dma_fence_cb *cb);
> int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
> struct dma_fence *dma,
> unsigned long timeout,
> gfp_t gfp);
> +
> int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
> struct reservation_object *resv,
> const struct dma_fence_ops *exclude,
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 74be9a49ef9e..48a2bca7fec3 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -2626,7 +2626,10 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
> goto error_deref_obj;
> }
>
> - timeline = i915_timeline_create(ctx->i915, ctx->name);
> + if (ctx->timeline)
> + timeline = i915_timeline_get(ctx->timeline);
> + else
> + timeline = i915_timeline_create(ctx->i915, ctx->name);
> if (IS_ERR(timeline)) {
> ret = PTR_ERR(timeline);
> goto error_deref_obj;
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index dc1c52f95cab..adb9fed86ef7 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1433,7 +1433,8 @@ struct drm_i915_gem_context_create_v2 {
> /* output: id of new context*/
> __u32 ctx_id;
> __u32 flags;
> -#define I915_GEM_CONTEXT_SHARE_GTT 0x1
> +#define I915_GEM_CONTEXT_SHARE_GTT 0x1
> +#define I915_GEM_CONTEXT_SINGLE_TIMELINE 0x2
> __u32 share_ctx;
> __u32 pad;
> };
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-09-25 8:45 UTC|newest]
Thread overview: 106+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-19 19:55 [PATCH 01/40] drm: Use default dma_fence hooks where possible for null syncobj Chris Wilson
2018-09-19 19:55 ` [PATCH 02/40] drm: Fix syncobj handing of schedule() returning 0 Chris Wilson
2018-09-20 14:13 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 03/40] drm/i915/selftests: Live tests emit requests and so require rpm Chris Wilson
2018-09-20 14:01 ` Tvrtko Ursulin
2018-09-20 14:47 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 04/40] drm/i915: Park the GPU on module load Chris Wilson
2018-09-20 14:02 ` Tvrtko Ursulin
2018-09-20 14:52 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 05/40] drm/i915: Handle incomplete Z_FINISH for compressed error states Chris Wilson
2018-09-19 19:55 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 06/40] drm/i915: Clear the error PTE just once on finish Chris Wilson
2018-09-19 19:55 ` [PATCH 07/40] drm/i915: Cache the error string Chris Wilson
2018-09-19 19:55 ` [PATCH 08/40] drm/i915/execlists: Avoid kicking priority on the current context Chris Wilson
2018-09-19 19:55 ` [PATCH 09/40] drm/i915/selftests: Free the batch along the contexts error path Chris Wilson
2018-09-20 8:30 ` Mika Kuoppala
2018-09-20 8:36 ` Chris Wilson
2018-09-20 9:19 ` Mika Kuoppala
2018-09-19 19:55 ` [PATCH 10/40] drm/i915/selftests: Basic stress test for rapid context switching Chris Wilson
2018-09-20 10:38 ` Mika Kuoppala
2018-09-20 10:46 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 11/40] drm/i915/execlists: Onion unwind for logical_ring_init() failure Chris Wilson
2018-09-20 14:18 ` Mika Kuoppala
2018-09-20 14:21 ` Tvrtko Ursulin
2018-09-20 19:59 ` Chris Wilson
2018-09-21 10:00 ` Tvrtko Ursulin
2018-09-21 10:01 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 12/40] drm/i915/execlists: Assert the queue is non-empty on unsubmitting Chris Wilson
2018-09-24 9:07 ` Tvrtko Ursulin
2018-09-25 7:41 ` Chris Wilson
2018-09-25 8:51 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 13/40] drm/i915: Reserve some priority bits for internal use Chris Wilson
2018-09-24 9:12 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 14/40] drm/i915: Combine multiple internal plists into the same i915_priolist bucket Chris Wilson
2018-09-24 10:25 ` Tvrtko Ursulin
2018-09-25 7:55 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 15/40] drm/i915: Priority boost for new clients Chris Wilson
2018-09-24 10:29 ` Tvrtko Ursulin
2018-09-25 8:01 ` Chris Wilson
2018-09-25 8:26 ` Chris Wilson
2018-09-25 8:57 ` Tvrtko Ursulin
2018-09-25 9:06 ` Chris Wilson
2018-09-25 9:08 ` Tvrtko Ursulin
2018-09-25 11:20 ` Michal Wajdeczko
2018-09-19 19:55 ` [PATCH 16/40] drm/i915: Pull scheduling under standalone lock Chris Wilson
2018-09-24 11:19 ` Tvrtko Ursulin
2018-09-25 8:19 ` Chris Wilson
2018-09-25 9:01 ` Tvrtko Ursulin
2018-09-25 9:10 ` Chris Wilson
2018-09-25 9:19 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 17/40] drm/i915: Priority boost for waiting clients Chris Wilson
2018-09-24 11:29 ` Tvrtko Ursulin
2018-09-25 9:00 ` Chris Wilson
2018-09-25 9:07 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 18/40] drm/i915: Report the number of closed vma held by each context in debugfs Chris Wilson
2018-09-24 11:57 ` Tvrtko Ursulin
2018-09-25 12:20 ` Chris Wilson
2018-09-19 19:55 ` [PATCH 19/40] drm/i915: Remove debugfs/i915_ppgtt_info Chris Wilson
2018-09-24 12:03 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 20/40] drm/i915: Track all held rpm wakerefs Chris Wilson
2018-09-19 19:55 ` [PATCH 21/40] drm/i915: Markup paired operations on wakerefs Chris Wilson
2018-09-19 19:55 ` [PATCH 22/40] drm/i915: Syntatic sugar for using intel_runtime_pm Chris Wilson
2018-09-24 12:08 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 23/40] drm/i915: Markup paired operations on display power domains Chris Wilson
2018-09-19 19:55 ` [PATCH 24/40] drm/i915: Track the wakeref used to initialise " Chris Wilson
2018-09-19 19:55 ` [PATCH 25/40] drm/i915/dp: Markup pps lock power well Chris Wilson
2018-09-19 19:55 ` [PATCH 26/40] drm/i915: Complain if hsw_get_pipe_config acquires the same power well twice Chris Wilson
2018-09-19 19:55 ` [PATCH 27/40] drm/i915: Mark up Ironlake ips with rpm wakerefs Chris Wilson
2018-09-19 19:55 ` [PATCH 28/40] drm/i915: Serialise concurrent calls to i915_gem_set_wedged() Chris Wilson
2018-09-19 19:55 ` [PATCH 29/40] drm/i915: Differentiate between ggtt->mutex and ppgtt->mutex Chris Wilson
2018-09-24 13:04 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 30/40] drm/i915: Pull all the reset functionality together into i915_reset.c Chris Wilson
2018-09-19 19:55 ` [PATCH 31/40] drm/i915: Make all GPU resets atomic Chris Wilson
2018-09-19 19:55 ` [PATCH 32/40] drm/i915: Introduce the i915_user_extension_method Chris Wilson
2018-09-24 13:20 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 33/40] drm/i915: Extend CREATE_CONTEXT to allow inheritance ala clone() Chris Wilson
2018-09-24 17:22 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 34/40] drm/i915: Allow contexts to share a single timeline across all engines Chris Wilson
2018-09-25 8:45 ` Tvrtko Ursulin [this message]
2018-09-19 19:55 ` [PATCH 35/40] drm/i915: Fix I915_EXEC_RING_MASK Chris Wilson
2018-09-25 8:46 ` [Intel-gfx] " Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 36/40] drm/i915: Re-arrange execbuf so context is known before engine Chris Wilson
2018-09-19 19:55 ` [PATCH 37/40] drm/i915: Allow a context to define its set of engines Chris Wilson
2018-09-27 11:28 ` Tvrtko Ursulin
2018-09-28 20:22 ` Chris Wilson
2018-10-01 8:30 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 38/40] drm/i915/execlists: Flush the CS events before unpinning Chris Wilson
2018-10-01 10:51 ` Tvrtko Ursulin
2018-10-01 11:06 ` Chris Wilson
2018-10-01 13:15 ` Tvrtko Ursulin
2018-10-01 13:26 ` Chris Wilson
2018-10-01 14:03 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 39/40] drm/i915/execlists: Refactor out can_merge_rq() Chris Wilson
2018-09-27 11:32 ` Tvrtko Ursulin
2018-09-28 20:11 ` Chris Wilson
2018-10-01 8:14 ` Tvrtko Ursulin
2018-10-01 8:18 ` Chris Wilson
2018-10-01 10:18 ` Tvrtko Ursulin
2018-09-19 19:55 ` [PATCH 40/40] drm/i915: Load balancing across a virtual engine Chris Wilson
2018-10-01 11:37 ` Tvrtko Ursulin
2018-09-19 21:54 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/40] drm: Use default dma_fence hooks where possible for null syncobj Patchwork
2018-09-19 22:08 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-19 22:17 ` ✗ Fi.CI.BAT: failure " Patchwork
2018-09-20 13:34 ` [PATCH 01/40] " Tvrtko Ursulin
2018-09-20 13:40 ` Chris Wilson
2018-09-20 13:54 ` Tvrtko Ursulin
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=b029d409-233b-d464-8d2a-40032881d159@linux.intel.com \
--to=tvrtko.ursulin@linux.intel.com \
--cc=chris@chris-wilson.co.uk \
--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.