[PATCH 2/3] drm/i915/guc: Keep the execbuf client allocated across reset
Chris Wilson
chris at chris-wilson.co.uk
Thu Nov 17 10:31:51 UTC 2016
In order to avoid some complexity in trying to reconstruct the
workqueues across reset, remember them instead.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_guc_submission.c | 68 ++++++++++++------------------
1 file changed, 27 insertions(+), 41 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 4462112725ef..b7f97aec2169 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -252,13 +252,6 @@ static int guc_update_doorbell_id(struct intel_guc *guc,
return host2guc_allocate_doorbell(guc, client);
}
-static int guc_init_doorbell(struct intel_guc *guc,
- struct i915_guc_client *client,
- uint16_t db_id)
-{
- return guc_update_doorbell_id(guc, client, db_id);
-}
-
static void guc_disable_doorbell(struct intel_guc *guc,
struct i915_guc_client *client)
{
@@ -779,9 +772,6 @@ static void guc_init_doorbell_hw(struct intel_guc *guc)
uint16_t db_id;
int i, err;
- /* Save client's original doorbell selection */
- db_id = client->doorbell_id;
-
for (i = 0; i < GUC_MAX_DOORBELLS; ++i) {
/* Skip if doorbell is OK */
if (guc_doorbell_check(guc, i))
@@ -793,7 +783,9 @@ static void guc_init_doorbell_hw(struct intel_guc *guc)
i, err);
}
- /* Restore to original value */
+ db_id = select_doorbell_register(guc, client->priority);
+ WARN_ON(db_id == GUC_INVALID_DOORBELL_ID);
+
err = guc_update_doorbell_id(guc, client, db_id);
if (err)
DRM_WARN("Failed to restore doorbell to %d, err %d\n",
@@ -883,8 +875,6 @@ guc_client_alloc(struct drm_i915_private *dev_priv,
guc_proc_desc_init(guc, client);
guc_ctx_desc_init(guc, client);
- if (guc_init_doorbell(guc, client, db_id))
- goto err;
DRM_DEBUG_DRIVER("new priority %u client %p for engine(s) 0x%x: ctx_index %u\n",
priority, client, client->engines, client->ctx_index);
@@ -1484,8 +1474,6 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv)
struct intel_guc *guc = &dev_priv->guc;
struct i915_vma *vma;
- /* Wipe bitmap & delete client in case of reinitialisation */
- bitmap_clear(guc->doorbell_bitmap, 0, GUC_MAX_DOORBELLS);
i915_guc_submission_disable(dev_priv);
if (!i915.enable_guc_submission)
@@ -1504,29 +1492,31 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv)
guc_log_create(guc);
guc_addon_create(guc);
+ guc->execbuf_client = guc_client_alloc(dev_priv,
+ INTEL_INFO(dev_priv)->ring_mask,
+ GUC_CTX_PRIORITY_KMD_NORMAL,
+ dev_priv->kernel_context);
+ if (!guc->execbuf_client) {
+ DRM_ERROR("Failed to create GuC client for execbuf!\n");
+ goto err;
+ }
+
return 0;
+
+err:
+ i915_guc_submission_fini(dev_priv);
+ return -ENOMEM;
}
int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
{
struct intel_guc *guc = &dev_priv->guc;
+ struct i915_guc_client *gc = guc->execbuf_client;
struct drm_i915_gem_request *request;
- struct i915_guc_client *client;
struct intel_engine_cs *engine;
enum intel_engine_id id;
- /* client for execbuf submission */
- client = guc_client_alloc(dev_priv,
- INTEL_INFO(dev_priv)->ring_mask,
- GUC_CTX_PRIORITY_KMD_NORMAL,
- dev_priv->kernel_context);
- if (!client) {
- DRM_ERROR("Failed to create normal GuC client!\n");
- return -ENOMEM;
- }
-
- guc->execbuf_client = client;
- host2guc_sample_forcewake(guc, client);
+ host2guc_sample_forcewake(guc, gc);
guc_init_doorbell_hw(guc);
/* Take over from manual control of ELSP (execlists) */
@@ -1535,12 +1525,11 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
engine->schedule = NULL;
/* Replay the current set of previously submitted requests */
- list_for_each_entry(request,
- &engine->timeline->requests, link) {
- client->wq_rsvd += sizeof(struct guc_wq_item);
- if (i915_sw_fence_done(&request->submit))
+ list_for_each_entry(request, &engine->timeline->requests, link)
+ if (i915_sw_fence_done(&request->submit)) {
+ gc->wq_rsvd += sizeof(struct guc_wq_item);
i915_guc_submit(request);
- }
+ }
}
return 0;
@@ -1548,21 +1537,18 @@ 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;
-
- if (!guc->execbuf_client)
- return;
-
/* Revert back to manual ELSP submission */
intel_execlists_enable_submission(dev_priv);
-
- guc_client_free(dev_priv, guc->execbuf_client);
- guc->execbuf_client = NULL;
}
void i915_guc_submission_fini(struct drm_i915_private *dev_priv)
{
struct intel_guc *guc = &dev_priv->guc;
+ struct i915_guc_client *gc;
+
+ gc = fetch_and_zero(&guc->execbuf_client);
+ if (gc)
+ guc_client_free(dev_priv, gc);
i915_vma_unpin_and_release(&guc->ads_vma);
i915_vma_unpin_and_release(&guc->log.vma);
--
2.10.2
More information about the Intel-gfx-trybot
mailing list