From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2 3/3] drm/i915: Only allocate preempt context when required
Date: Wed, 31 Jan 2018 16:38:02 +0200 [thread overview]
Message-ID: <87607iw0tx.fsf@gaia.fi.intel.com> (raw)
In-Reply-To: <20180131094703.3676-3-chris@chris-wilson.co.uk>
Chris Wilson <chris@chris-wilson.co.uk> writes:
> If we remove some hardcoded assumptions about the preempt context having
> a fixed id, reserved from use by normal user contexts, we may only
> allocate the i915_gem_context when required. Then the subsequent
> decisions on using preemption reduce to having the preempt context
> available.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Michal Winiarski <michal.winiarski@intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> Cc: Mika Kuoppala <mika.kuoppala@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> ---
> drivers/gpu/drm/i915/i915_gem_context.c | 29 ++++++++++++------------
> drivers/gpu/drm/i915/intel_engine_cs.c | 6 ++---
> drivers/gpu/drm/i915/intel_guc_submission.c | 24 +++++++++++---------
> drivers/gpu/drm/i915/intel_lrc.c | 17 +++++++++-----
> drivers/gpu/drm/i915/intel_ringbuffer.h | 5 ++++
> drivers/gpu/drm/i915/selftests/mock_gem_device.c | 6 -----
> 6 files changed, 46 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 648e7536ff51..d69c8f1a4e78 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -449,10 +449,14 @@ destroy_kernel_context(struct i915_gem_context **ctxp)
> i915_gem_context_free(ctx);
> }
>
> +static bool needs_preempt_context(struct drm_i915_private *i915)
> +{
> + return HAS_LOGICAL_RING_PREEMPTION(i915);
> +}
> +
> int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
> {
> struct i915_gem_context *ctx;
> - int err;
>
> GEM_BUG_ON(dev_priv->kernel_context);
Please consider adding
GEM_BUG_ON(dev_priv->preempt_context);
here even tho the kernel_context should act as a master guard for init ordering
errors. Even if no other than documenting that we expect a clean slate
in this regard also.
>
> @@ -468,8 +472,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
> ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_MIN);
> if (IS_ERR(ctx)) {
> DRM_ERROR("Failed to create default global context\n");
> - err = PTR_ERR(ctx);
> - goto err;
> + return PTR_ERR(ctx);
> }
> /*
> * For easy recognisablity, we want the kernel context to be 0 and then
> @@ -479,23 +482,18 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
> dev_priv->kernel_context = ctx;
>
> /* highest priority; preempting task */
> - ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
> - if (IS_ERR(ctx)) {
> - DRM_ERROR("Failed to create default preempt context\n");
> - err = PTR_ERR(ctx);
> - goto err_kernel_context;
It seems this error path has been wrong all along.
> + if (needs_preempt_context(dev_priv)) {
> + ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
> + if (!IS_ERR(ctx))
> + dev_priv->preempt_context = ctx;
> + else
> + DRM_ERROR("Failed to create preempt context; disabling preemption\n");
> }
> - dev_priv->preempt_context = ctx;
>
> DRM_DEBUG_DRIVER("%s context support initialized\n",
> dev_priv->engine[RCS]->context_size ? "logical" :
> "fake");
> return 0;
> -
> -err_kernel_context:
> - destroy_kernel_context(&dev_priv->kernel_context);
> -err:
> - return err;
> }
>
> void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
> @@ -521,7 +519,8 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915)
> {
> lockdep_assert_held(&i915->drm.struct_mutex);
>
> - destroy_kernel_context(&i915->preempt_context);
> + if (i915->preempt_context)
> + destroy_kernel_context(&i915->preempt_context);
> destroy_kernel_context(&i915->kernel_context);
>
> /* Must free all deferred contexts (via flush_workqueue) first */
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
> index 7eebfbb95e89..bf634432c9c6 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -631,7 +631,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
> * Similarly the preempt context must always be available so that
> * we can interrupt the engine at any time.
> */
> - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) {
> + if (engine->i915->preempt_context) {
> ring = engine->context_pin(engine,
> engine->i915->preempt_context);
> if (IS_ERR(ring)) {
> @@ -656,7 +656,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
> err_breadcrumbs:
> intel_engine_fini_breadcrumbs(engine);
> err_unpin_preempt:
> - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
> + if (engine->i915->preempt_context)
> engine->context_unpin(engine, engine->i915->preempt_context);
> err_unpin_kernel:
> engine->context_unpin(engine, engine->i915->kernel_context);
> @@ -686,7 +686,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
> if (engine->default_state)
> i915_gem_object_put(engine->default_state);
>
> - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
> + if (engine->i915->preempt_context)
> engine->context_unpin(engine, engine->i915->preempt_context);
> engine->context_unpin(engine, engine->i915->kernel_context);
> }
> diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
> index 4ea65df05e02..b43b58cc599b 100644
> --- a/drivers/gpu/drm/i915/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/intel_guc_submission.c
> @@ -688,7 +688,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
> goto unlock;
>
> if (port_isset(port)) {
> - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) {
> + if (engine->i915->preempt_context) {
> struct guc_preempt_work *preempt_work =
> &engine->i915->guc.preempt_work[engine->id];
>
> @@ -984,17 +984,19 @@ static int guc_clients_create(struct intel_guc *guc)
> }
> guc->execbuf_client = client;
>
> - client = guc_client_alloc(dev_priv,
> - INTEL_INFO(dev_priv)->ring_mask,
> - GUC_CLIENT_PRIORITY_KMD_HIGH,
> - dev_priv->preempt_context);
> - if (IS_ERR(client)) {
> - DRM_ERROR("Failed to create GuC client for preemption!\n");
> - guc_client_free(guc->execbuf_client);
> - guc->execbuf_client = NULL;
> - return PTR_ERR(client);
> + if (dev_priv->preempt_context) {
> + client = guc_client_alloc(dev_priv,
> + INTEL_INFO(dev_priv)->ring_mask,
> + GUC_CLIENT_PRIORITY_KMD_HIGH,
> + dev_priv->preempt_context);
> + if (IS_ERR(client)) {
> + DRM_ERROR("Failed to create GuC client for preemption!\n");
> + guc_client_free(guc->execbuf_client);
> + guc->execbuf_client = NULL;
> + return PTR_ERR(client);
> + }
> + guc->preempt_client = client;
> }
> - guc->preempt_client = client;
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 5390894001f0..221b62d72c72 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -161,7 +161,6 @@
> #define EXECLISTS_REQUEST_SIZE 64 /* bytes */
> #define WA_TAIL_DWORDS 2
> #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS)
> -#define PREEMPT_ID 0x1
>
> static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
> struct intel_engine_cs *engine);
> @@ -448,7 +447,8 @@ static void inject_preempt_context(struct intel_engine_cs *engine)
> &engine->i915->preempt_context->engine[engine->id];
> unsigned int n;
>
> - GEM_BUG_ON(engine->i915->preempt_context->hw_id != PREEMPT_ID);
> + GEM_BUG_ON(engine->execlists.preempt_complete_status !=
> + upper_32_bits(ce->lrc_desc));
> GEM_BUG_ON(!IS_ALIGNED(ce->ring->size, WA_TAIL_BYTES));
>
> memset(ce->ring->vaddr + ce->ring->tail, 0, WA_TAIL_BYTES);
> @@ -528,7 +528,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
> if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_HWACK))
> goto unlock;
>
> - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915) &&
> + if (engine->i915->preempt_context &&
> rb_entry(rb, struct i915_priolist, node)->priority >
> max(last->priotree.priority, 0)) {
> /*
> @@ -844,7 +844,7 @@ static void execlists_submission_tasklet(unsigned long data)
> GEM_BUG_ON(status & GEN8_CTX_STATUS_IDLE_ACTIVE);
>
> if (status & GEN8_CTX_STATUS_COMPLETE &&
> - buf[2*head + 1] == PREEMPT_ID) {
> + buf[2*head + 1] == execlists->preempt_complete_status) {
> GEM_TRACE("%s preempt-idle\n", engine->name);
>
> execlists_cancel_port_requests(execlists);
> @@ -1910,7 +1910,7 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine)
> engine->i915->caps.scheduler =
> I915_SCHEDULER_CAP_ENABLED |
> I915_SCHEDULER_CAP_PRIORITY;
> - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
> + if (engine->i915->preempt_context)
> engine->i915->caps.scheduler |= I915_SCHEDULER_CAP_PREEMPTION;
> }
>
> @@ -1988,6 +1988,11 @@ static int logical_ring_init(struct intel_engine_cs *engine)
> engine->execlists.elsp =
> engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine));
>
> + engine->execlists.preempt_complete_status = ~0u;
This is to ensure that we catch a rogue status? Atleast we will
bug on of preempting with this status as the EXECLIST_ACTIVE_PREEMPT
will be false.
> + if (engine->i915->preempt_context)
> + engine->execlists.preempt_complete_status =
> + upper_32_bits(engine->i915->preempt_context->engine[engine->id].lrc_desc);
We have not upgraded the descriptor yet, so just use preempt_context->hw_id;
I would also like duplicate, from i915_gem_context.c, the assertion that
hw_id needs to be <= INT_MAX but didn't find a good spot.
-Mika
> +
> return 0;
>
> error:
> @@ -2250,7 +2255,7 @@ populate_lr_context(struct i915_gem_context *ctx,
> if (!engine->default_state)
> regs[CTX_CONTEXT_CONTROL + 1] |=
> _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
> - if (ctx->hw_id == PREEMPT_ID)
> + if (ctx == ctx->i915->preempt_context)
> regs[CTX_CONTEXT_CONTROL + 1] |=
> _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
> CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT);
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index c5ff203e42d6..03be8995f415 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -279,6 +279,11 @@ struct intel_engine_execlists {
> * @csb_use_mmio: access csb through mmio, instead of hwsp
> */
> bool csb_use_mmio;
> +
> + /**
> + * @preempt_complete_status: expected CSB upon completing preemption
> + */
> + u32 preempt_complete_status;
> };
>
> #define INTEL_ENGINE_CS_MAX_NAME 8
> diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> index 1bc61f3f76fc..3175db70cc6e 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> @@ -243,16 +243,10 @@ struct drm_i915_private *mock_gem_device(void)
> if (!i915->kernel_context)
> goto err_engine;
>
> - i915->preempt_context = mock_context(i915, NULL);
> - if (!i915->preempt_context)
> - goto err_kernel_context;
> -
> WARN_ON(i915_gemfs_init(i915));
>
> return i915;
>
> -err_kernel_context:
> - i915_gem_context_put(i915->kernel_context);
> err_engine:
> for_each_engine(engine, i915, id)
> mock_engine_free(engine);
> --
> 2.15.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2018-01-31 14:38 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-31 9:47 [PATCH v2 1/3] drm/i915/guc: Allow preempt-client to be NULL Chris Wilson
2018-01-31 9:47 ` [PATCH v2 2/3] drm/i915: Move the scheduler feature bits into the purview of the engines Chris Wilson
2018-01-31 13:58 ` Mika Kuoppala
2018-02-01 18:54 ` Chris Wilson
2018-02-01 19:02 ` [PATCH v2] " Chris Wilson
2018-02-02 13:55 ` Mika Kuoppala
2018-02-02 14:06 ` Lis, Tomasz
2018-01-31 9:47 ` [PATCH v2 3/3] drm/i915: Only allocate preempt context when required Chris Wilson
2018-01-31 14:38 ` Mika Kuoppala [this message]
2018-01-31 15:25 ` Chris Wilson
2018-02-03 10:40 ` [PATCH v2] " Chris Wilson
2018-01-31 11:01 ` ✗ Fi.CI.BAT: warning for series starting with [v2,1/3] drm/i915/guc: Allow preempt-client to be NULL Patchwork
2018-01-31 11:31 ` [PATCH v2 1/3] " Mika Kuoppala
2018-01-31 11:34 ` Chris Wilson
2018-01-31 12:42 ` Mika Kuoppala
2018-01-31 12:03 ` [PATCH v2] " Chris Wilson
2018-01-31 13:14 ` Mika Kuoppala
2018-01-31 13:00 ` ✓ Fi.CI.BAT: success for series starting with [v2] drm/i915/guc: Allow preempt-client to be NULL (rev2) Patchwork
2018-01-31 16:44 ` ✓ Fi.CI.IGT: " Patchwork
2018-02-01 19:22 ` ✗ Fi.CI.BAT: failure for series starting with [v2] drm/i915/guc: Allow preempt-client to be NULL (rev3) Patchwork
2018-02-03 11:17 ` ✓ Fi.CI.BAT: success for series starting with [v2] drm/i915/guc: Allow preempt-client to be NULL (rev4) Patchwork
2018-02-04 6:51 ` ✗ Fi.CI.IGT: failure " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2018-02-07 21:05 [PATCH v2 1/3] drm/i915/guc: Allow preempt-client to be NULL Chris Wilson
2018-02-07 21:05 ` [PATCH v2 3/3] drm/i915: Only allocate preempt context when required Chris Wilson
2018-02-07 22:34 ` Michel Thierry
2018-02-07 22:44 ` Chris Wilson
2018-02-08 7:33 ` Chris Wilson
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=87607iw0tx.fsf@gaia.fi.intel.com \
--to=mika.kuoppala@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.