All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 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.