From: Dave Gordon <david.s.gordon@intel.com>
To: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 3/5] drm/i915/guc: use a separate GuC client for each engine
Date: Tue, 19 Jul 2016 16:13:41 +0100 [thread overview]
Message-ID: <578E43A5.9000402@intel.com> (raw)
In-Reply-To: <578E4119.7050409@linux.intel.com>
On 19/07/16 16:02, Tvrtko Ursulin wrote:
>
> On 19/07/16 13:59, Dave Gordon wrote:
>> When using a single GuC client for multiple engines, the i915 driver has
>> to merge all work items into a single work queue, which the GuC firmware
>> then demultiplexes into separate submission queues per engine. In
>> theory, this could lead to the single queue becoming a bottleneck in
>> which an excess of outstanding work for one or more engines might
>> prevent work for an idle engine reaching the hardware.
>>
>> To reduce this risk, we can create one GuC client per engine. Each will
>> have its own workqueue, to be used only for work targeting a single
>> engine, so there will be no cross-engine contention for workqueue slots.
>>
>> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_debugfs.c | 25 ++++++++++++++++-----
>> drivers/gpu/drm/i915/i915_guc_submission.c | 35
>> +++++++++++++++++++-----------
>> drivers/gpu/drm/i915/intel_guc.h | 2 +-
>> 3 files changed, 42 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
>> b/drivers/gpu/drm/i915/i915_debugfs.c
>> index 90aef45..5cbb8ef 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -2570,20 +2570,26 @@ static int i915_guc_info(struct seq_file *m,
>> void *data)
>> struct drm_device *dev = node->minor->dev;
>> struct drm_i915_private *dev_priv = to_i915(dev);
>> struct intel_guc guc;
>> - struct i915_guc_client client = {};
>> + struct i915_guc_client *clients;
>> struct intel_engine_cs *engine;
>> + enum intel_engine_id id;
>> u64 total = 0;
>>
>> if (!HAS_GUC_SCHED(dev_priv))
>> return 0;
>>
>> + clients = kcalloc(I915_NUM_ENGINES, sizeof(*clients), GFP_KERNEL);
>> + if (clients == NULL)
>> + return -ENOMEM;
>> +
>> if (mutex_lock_interruptible(&dev->struct_mutex))
>> - return 0;
>> + goto done;
>>
>> /* Take a local copy of the GuC data, so we can dump it at
>> leisure */
>> guc = dev_priv->guc;
>> - if (guc.execbuf_client)
>> - client = *guc.execbuf_client;
>> + for_each_engine_id(engine, dev_priv, id)
>> + if (guc.exec_clients[id])
>> + clients[id] = *guc.exec_clients[id];
>>
>> mutex_unlock(&dev->struct_mutex);
>>
>> @@ -2606,11 +2612,18 @@ static int i915_guc_info(struct seq_file *m,
>> void *data)
>> }
>> seq_printf(m, "\t%s: %llu\n", "Total", total);
>>
>> - seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client);
>> - i915_guc_client_info(m, dev_priv, &client);
>> + for_each_engine_id(engine, dev_priv, id) {
>> + seq_printf(m, "\nGuC exec_client[%d] @ %p:\n",
>> + id, guc.exec_clients[id]);
>
> Minor and not a blocker for this patch, but I would potentially
> re-consider if printing out the client pointer is useful.
It's really only useful to know whether it's NULL or not; but printing
the pointer itself is simpler than printing a message saying that. This
is a debugfs interface, so the content is pretty much ad-hoc.
.Dave.
>> + if (guc.exec_clients[id])
>> + i915_guc_client_info(m, dev_priv, &clients[id]);
>> + }
>>
>> /* Add more as required ... */
>>
>> +done:
>> + kfree(clients);
>> +
>> return 0;
>> }
>>
>> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c
>> b/drivers/gpu/drm/i915/i915_guc_submission.c
>> index dc5f485..b0f9945 100644
>> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
>> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
>> @@ -434,7 +434,9 @@ static void guc_fini_ctx_desc(struct intel_guc *guc,
>> int i915_guc_wq_check_space(struct drm_i915_gem_request *request)
>> {
>> const size_t wqi_size = sizeof(struct guc_wq_item);
>> - struct i915_guc_client *gc = request->i915->guc.execbuf_client;
>> + enum intel_engine_id engine_id = request->engine->id;
>> + struct intel_guc *guc = &request->i915->guc;
>> + struct i915_guc_client *gc = guc->exec_clients[engine_id];
>> struct guc_process_desc *desc;
>> u32 freespace;
>>
>> @@ -589,7 +591,7 @@ int i915_guc_submit(struct drm_i915_gem_request *rq)
>> {
>> unsigned int engine_id = rq->engine->id;
>> struct intel_guc *guc = &rq->i915->guc;
>> - struct i915_guc_client *client = guc->execbuf_client;
>> + struct i915_guc_client *client = guc->exec_clients[engine_id];
>> int b_ret;
>>
>> guc_add_workqueue_item(client, rq);
>> @@ -723,7 +725,7 @@ static bool guc_doorbell_check(struct intel_guc
>> *guc, uint16_t db_id)
>> */
>> static void guc_init_doorbell_hw(struct intel_guc *guc)
>> {
>> - struct i915_guc_client *client = guc->execbuf_client;
>> + struct i915_guc_client *client = guc->exec_clients[RCS];
>> uint16_t db_id;
>> int i, err;
>>
>> @@ -1004,17 +1006,21 @@ int i915_guc_submission_enable(struct
>> drm_i915_private *dev_priv)
>> {
>> struct intel_guc *guc = &dev_priv->guc;
>> struct i915_guc_client *client;
>> + struct intel_engine_cs *engine;
>>
>> - /* client for execbuf submission */
>> - client = guc_client_alloc(dev_priv,
>> - GUC_CTX_PRIORITY_KMD_NORMAL,
>> - dev_priv->kernel_context);
>> - if (!client) {
>> - DRM_ERROR("Failed to create execbuf guc_client\n");
>> - return -ENOMEM;
>> + for_each_engine(engine, dev_priv) {
>> + /* client for execbuf submission */
>> + client = guc_client_alloc(dev_priv,
>> + GUC_CTX_PRIORITY_KMD_NORMAL,
>> + dev_priv->kernel_context);
>> + if (!client) {
>> + DRM_ERROR("Failed to create GuC client(s)\n");
>> + return -ENOMEM;
>> + }
>> +
>> + guc->exec_clients[engine->id] = client;
>> }
>>
>> - guc->execbuf_client = client;
>> host2guc_sample_forcewake(guc, client);
>> guc_init_doorbell_hw(guc);
>>
>> @@ -1024,9 +1030,12 @@ int i915_guc_submission_enable(struct
>> drm_i915_private *dev_priv)
>> void i915_guc_submission_disable(struct drm_i915_private *dev_priv)
>> {
>> struct intel_guc *guc = &dev_priv->guc;
>> + struct intel_engine_cs *engine;
>>
>> - guc_client_free(dev_priv, guc->execbuf_client);
>> - guc->execbuf_client = NULL;
>> + for_each_engine(engine, dev_priv) {
>> + guc_client_free(dev_priv, guc->exec_clients[engine->id]);
>> + guc->exec_clients[engine->id] = NULL;
>> + }
>> }
>>
>> void i915_guc_submission_fini(struct drm_i915_private *dev_priv)
>> diff --git a/drivers/gpu/drm/i915/intel_guc.h
>> b/drivers/gpu/drm/i915/intel_guc.h
>> index 3e3e743..7b4cc4d 100644
>> --- a/drivers/gpu/drm/i915/intel_guc.h
>> +++ b/drivers/gpu/drm/i915/intel_guc.h
>> @@ -132,7 +132,7 @@ struct intel_guc {
>> struct drm_i915_gem_object *ctx_pool_obj;
>> struct ida ctx_ids;
>>
>> - struct i915_guc_client *execbuf_client;
>> + struct i915_guc_client *exec_clients[I915_NUM_ENGINES];
>>
>> DECLARE_BITMAP(doorbell_bitmap, GUC_MAX_DOORBELLS);
>> uint32_t db_cacheline; /* Cyclic counter mod pagesize */
>>
>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> 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:[~2016-07-19 15:13 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-19 12:59 [PATCH 1/5] drm/i915/guc: doorbell reset should avoid used doorbells Dave Gordon
2016-07-19 12:59 ` [PATCH 2/5] drm/i915/guc: refactor guc_init_doorbell_hw() Dave Gordon
2016-07-19 14:51 ` Tvrtko Ursulin
2016-07-19 12:59 ` [PATCH 3/5] drm/i915/guc: use a separate GuC client for each engine Dave Gordon
2016-07-19 15:02 ` Tvrtko Ursulin
2016-07-19 15:13 ` Dave Gordon [this message]
2016-07-19 12:59 ` [PATCH 4/5] drm/i915/guc: add engine mask to GuC client & pass to GuC Dave Gordon
2016-07-19 15:06 ` Tvrtko Ursulin
2016-07-27 20:06 ` kbuild test robot
2016-07-19 12:59 ` [PATCH 5/5] drm/i915/guc: use for_each_engine_id() where appropriate Dave Gordon
2016-07-19 15:09 ` Tvrtko Ursulin
2016-07-19 14:16 ` ✗ Ro.CI.BAT: failure for series starting with [1/5] drm/i915/guc: doorbell reset should avoid used doorbells Patchwork
2016-07-19 15:07 ` Dave Gordon
2016-07-19 14:43 ` [PATCH 1/5] " 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=578E43A5.9000402@intel.com \
--to=david.s.gordon@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=tvrtko.ursulin@linux.intel.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox