From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Dave Gordon <david.s.gordon@intel.com>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 3/4] drm/i915/guc: refactor doorbell management code
Date: Wed, 8 Jun 2016 14:11:41 +0100 [thread overview]
Message-ID: <5758198D.5020407@linux.intel.com> (raw)
In-Reply-To: <1465383329-14885-4-git-send-email-david.s.gordon@intel.com>
On 08/06/16 11:55, Dave Gordon wrote:
> During a hibernate/resume cycle, the driver, the GuC, and the doorbell
> hardware can end up in inconsistent states. This patch refactors the
> driver's handling and tracking of doorbells, in preparation for a later
> one which will resolve the issue.
Perhaps a few word on the goal, method and result of refactoring. Would
be good for documentation and easier review.
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> ---
> drivers/gpu/drm/i915/i915_guc_submission.c | 87 ++++++++++++++++++------------
> 1 file changed, 53 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 7510841..eef67c8 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -174,36 +174,63 @@ static int host2guc_sample_forcewake(struct intel_guc *guc,
> * client object which contains the page being used for the doorbell
> */
>
> -static void guc_init_doorbell(struct intel_guc *guc,
> - struct i915_guc_client *client)
> +static int guc_update_doorbell_id(struct i915_guc_client *client,
> + struct guc_doorbell_info *doorbell,
> + u16 new_id)
> {
> - struct guc_doorbell_info *doorbell;
> + struct sg_table *sg = client->guc->ctx_pool_obj->pages;
> + void *doorbell_bitmap = client->guc->doorbell_bitmap;
> + struct guc_context_desc desc;
> + size_t len;
> +
> + if (client->doorbell_id != GUC_INVALID_DOORBELL_ID &&
> + test_bit(client->doorbell_id, doorbell_bitmap)) {
> + /* Deactivate the old doorbell */
> + doorbell->db_status = GUC_DOORBELL_DISABLED;
> + (void)host2guc_release_doorbell(client->guc, client);
> + clear_bit(client->doorbell_id, doorbell_bitmap);
> + }
>
> - doorbell = client->client_base + client->doorbell_offset;
> + /* Update the GuC's idea of the doorbell ID */
> + len = sg_pcopy_to_buffer(sg->sgl, sg->nents, &desc, sizeof(desc),
> + sizeof(desc) * client->ctx_index);
> + if (len != sizeof(desc))
> + return -EFAULT;
> + desc.db_id = new_id;
> + len = sg_pcopy_from_buffer(sg->sgl, sg->nents, &desc, sizeof(desc),
> + sizeof(desc) * client->ctx_index);
> + if (len != sizeof(desc))
> + return -EFAULT;
> +
> + client->doorbell_id = new_id;
> + if (new_id == GUC_INVALID_DOORBELL_ID)
> + return 0;
>
> + /* Activate the new doorbell */
> + set_bit(client->doorbell_id, doorbell_bitmap);
> doorbell->db_status = GUC_DOORBELL_ENABLED;
> doorbell->cookie = 0;
> + return host2guc_allocate_doorbell(client->guc, client);
A bunch of new code here which wasn't done on doorbell init before.
Populating the ctx_pool_obj and hust2guc call. I think the commit needs
to explain what is happening here.
Maybe it is mostly a matter of copying over some text from the cover
letter, but ideally it should explain what it is doing more precisely.
> }
>
> -static void guc_disable_doorbell(struct intel_guc *guc,
> - struct i915_guc_client *client)
> +static void guc_init_doorbell(struct intel_guc *guc,
> + struct i915_guc_client *client,
> + uint16_t db_id)
> {
> - struct drm_i915_private *dev_priv = guc_to_i915(guc);
> struct guc_doorbell_info *doorbell;
> - i915_reg_t drbreg = GEN8_DRBREGL(client->doorbell_id);
> - int value;
>
> doorbell = client->client_base + client->doorbell_offset;
>
> - doorbell->db_status = GUC_DOORBELL_DISABLED;
> -
> - I915_WRITE(drbreg, I915_READ(drbreg) & ~GEN8_DRB_VALID);
> + guc_update_doorbell_id(client, doorbell, db_id);
> +}
This function does not end up doing anything now, just a pass-through to
guc_update_doorbell_id.
What happens to the write to drbreg ? It is completely gone and also
from the init doorbell path together with the write to another register.
>
> - value = I915_READ(drbreg);
> - WARN_ON((value & GEN8_DRB_VALID) != 0);
> +static void guc_disable_doorbell(struct intel_guc *guc,
> + struct i915_guc_client *client)
> +{
> + struct guc_doorbell_info *doorbell;
>
> - I915_WRITE(GEN8_DRBREGU(client->doorbell_id), 0);
> - I915_WRITE(drbreg, 0);
> + doorbell = client->client_base + client->doorbell_offset;
> + guc_update_doorbell_id(client, doorbell, GUC_INVALID_DOORBELL_ID);
>
> /* XXX: wait for any interrupts */
> /* XXX: wait for workqueue to drain */
> @@ -251,7 +278,7 @@ static uint16_t assign_doorbell(struct intel_guc *guc, uint32_t priority)
> if (id == end)
> id = GUC_INVALID_DOORBELL_ID;
> else
> - bitmap_set(guc->doorbell_bitmap, id, 1);
> + set_bit(id, guc->doorbell_bitmap);
set_bit is atomic - is there a reason it is required here?
Actually the same question for the clear_bit above, where it was
bitmap_clear before.
>
> DRM_DEBUG_DRIVER("assigned %s priority doorbell id 0x%x\n",
> hi_pri ? "high" : "normal", id);
> @@ -259,11 +286,6 @@ static uint16_t assign_doorbell(struct intel_guc *guc, uint32_t priority)
> return id;
> }
>
> -static void release_doorbell(struct intel_guc *guc, uint16_t id)
> -{
> - bitmap_clear(guc->doorbell_bitmap, id, 1);
> -}
> -
> /*
> * Initialise the process descriptor shared with the GuC firmware.
> */
> @@ -657,8 +679,6 @@ static void guc_client_free(struct drm_device *dev,
> */
>
> if (client->client_base) {
> - uint16_t db_id = client->doorbell_id;
> -
> /*
> * If we got as far as setting up a doorbell, make sure
> * we shut it down before unmapping & deallocating the
> @@ -666,12 +686,8 @@ static void guc_client_free(struct drm_device *dev,
> * GuC that we've finished with it, finally deallocate
> * it in our bitmap
> */
> - if (db_id != GUC_INVALID_DOORBELL_ID) {
> + if (client->doorbell_id != GUC_INVALID_DOORBELL_ID)
> guc_disable_doorbell(guc, client);
> - if (test_bit(db_id, guc->doorbell_bitmap))
> - host2guc_release_doorbell(guc, client);
> - release_doorbell(guc, db_id);
> - }
>
> kunmap(kmap_to_page(client->client_base));
> }
> @@ -706,6 +722,7 @@ static struct i915_guc_client *guc_client_alloc(struct drm_device *dev,
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_guc *guc = &dev_priv->guc;
> struct drm_i915_gem_object *obj;
> + uint16_t db_id;
>
> client = kzalloc(sizeof(*client), GFP_KERNEL);
> if (!client)
> @@ -746,22 +763,24 @@ static struct i915_guc_client *guc_client_alloc(struct drm_device *dev,
> else
> client->proc_desc_offset = (GUC_DB_SIZE / 2);
>
> - client->doorbell_id = assign_doorbell(guc, client->priority);
> - if (client->doorbell_id == GUC_INVALID_DOORBELL_ID)
> + db_id = assign_doorbell(guc, client->priority);
> + if (db_id == GUC_INVALID_DOORBELL_ID)
> /* XXX: evict a doorbell instead */
> goto err;
>
> guc_init_proc_desc(guc, client);
> guc_init_ctx_desc(guc, client);
> - guc_init_doorbell(guc, client);
> + guc_init_doorbell(guc, client, db_id);
>
> /* XXX: Any cache flushes needed? General domain mgmt calls? */
>
> if (host2guc_allocate_doorbell(guc, client))
> goto err;
>
> - DRM_DEBUG_DRIVER("new priority %u client %p: ctx_index %u db_id %u\n",
> - priority, client, client->ctx_index, client->doorbell_id);
> + DRM_DEBUG_DRIVER("new priority %u client %p: ctx_index %u\n",
> + priority, client, client->ctx_index);
> + DRM_DEBUG_DRIVER("doorbell id %u, cacheline offset 0x%x\n",
> + client->doorbell_id, client->doorbell_offset);
>
> return client;
>
>
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-06-08 13:15 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-08 10:55 [PATCH 0/4] drm/i915: updates to GuC doorbell handling Dave Gordon
2016-06-08 10:55 ` [PATCH 1/4] drm/i915/guc: add doorbell map to debugfs/i915_guc_info Dave Gordon
2016-06-08 12:32 ` Tvrtko Ursulin
2016-06-08 10:55 ` [PATCH 2/4] drm/i915/guc: move guc_ring_doorbell() nearer to callsite Dave Gordon
2016-06-08 12:47 ` Tvrtko Ursulin
2016-06-08 10:55 ` [PATCH 3/4] drm/i915/guc: refactor doorbell management code Dave Gordon
2016-06-08 13:11 ` Tvrtko Ursulin [this message]
2016-06-10 11:37 ` Dave Gordon
2016-06-08 10:55 ` [PATCH 4/4] drm/i915/guc: (re)initialise doorbell h/w when enabling GuC submission Dave Gordon
2016-06-08 11:41 ` ✓ Ro.CI.BAT: success for drm/i915: updates to GuC doorbell handling 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=5758198D.5020407@linux.intel.com \
--to=tvrtko.ursulin@linux.intel.com \
--cc=david.s.gordon@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox