diff options
author | Oscar Mateo | 2017-03-22 18:39:53 +0100 |
---|---|---|
committer | Joonas Lahtinen | 2017-03-23 13:58:42 +0100 |
commit | b09935a60d55265027db9f2b0177aa24317b714c (patch) | |
tree | cdd3965316f04ebb46bda48a4b51a734e0ab6e7c /drivers/gpu/drm/i915/i915_guc_submission.c | |
parent | drm/i915/guc: A little bit more of doorbell sanitization (diff) | |
download | kernel-qcow2-linux-b09935a60d55265027db9f2b0177aa24317b714c.tar.gz kernel-qcow2-linux-b09935a60d55265027db9f2b0177aa24317b714c.tar.xz kernel-qcow2-linux-b09935a60d55265027db9f2b0177aa24317b714c.zip |
drm/i915/guc: Refactor the concept "GuC context descriptor" into "GuC stage descriptor"
A GuC context and a HW context are in no way related, so the name "GuC context descriptor"
is very unfortunate, because a new reader of the code gets overwhelmed very quickly with
a lot of things called "context" that refer to different things. We can improve legibility
a lot by simply renaming a few objects in the GuC code.
v2:
- Rebased
- s/ctx_desc_pool/stage_desc_pool
- Move some explanations to the definition of the guc_stage_desc struct (Chris)
v3:
- Calculate gemsize with less intermediate steps (Joonas)
- Use BIT() macro (Joonas)
Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_guc_submission.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_guc_submission.c | 118 |
1 files changed, 60 insertions, 58 deletions
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index e2ad365679c3..41ec8af526a5 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -37,16 +37,16 @@ * descriptor and a workqueue (all of them inside a single gem object that * contains all required pages for these elements). * - * GuC context descriptor: + * GuC stage descriptor: * During initialization, the driver allocates a static pool of 1024 such * descriptors, and shares them with the GuC. * Currently, there exists a 1:1 mapping between a i915_guc_client and a - * guc_context_desc (via the client's context_index), so effectively only - * one guc_context_desc gets used. This context descriptor lets the GuC know - * about the doorbell, workqueue and process descriptor. Theoretically, it also - * lets the GuC know about our HW contexts (Context ID, etc...), but we actually + * guc_stage_desc (via the client's stage_id), so effectively only one + * gets used. This stage descriptor lets the GuC know about the doorbell, + * workqueue and process descriptor. Theoretically, it also lets the GuC + * know about our HW contexts (context ID, etc...), but we actually * employ a kind of submission where the GuC uses the LRCA sent via the work - * item instead (the single guc_context_desc associated to execbuf client + * item instead (the single guc_stage_desc associated to execbuf client * contains information about the default kernel context only, but this is * essentially unused). This is called a "proxy" submission. * @@ -82,7 +82,7 @@ static inline bool is_high_priority(struct i915_guc_client* client) { - return client->priority <= GUC_CTX_PRIORITY_HIGH; + return client->priority <= GUC_CLIENT_PRIORITY_HIGH; } static int __reserve_doorbell(struct i915_guc_client *client) @@ -112,7 +112,7 @@ static int __reserve_doorbell(struct i915_guc_client *client) __set_bit(id, client->guc->doorbell_bitmap); client->doorbell_id = id; DRM_DEBUG_DRIVER("client %u (high prio=%s) reserved doorbell: %d\n", - client->ctx_index, yesno(is_high_priority(client)), + client->stage_id, yesno(is_high_priority(client)), id); return 0; } @@ -129,31 +129,31 @@ static void __unreserve_doorbell(struct i915_guc_client *client) * Tell the GuC to allocate or deallocate a specific doorbell */ -static int __guc_allocate_doorbell(struct intel_guc *guc, u32 ctx_index) +static int __guc_allocate_doorbell(struct intel_guc *guc, u32 stage_id) { u32 action[] = { INTEL_GUC_ACTION_ALLOCATE_DOORBELL, - ctx_index + stage_id }; return intel_guc_send(guc, action, ARRAY_SIZE(action)); } -static int __guc_deallocate_doorbell(struct intel_guc *guc, u32 ctx_index) +static int __guc_deallocate_doorbell(struct intel_guc *guc, u32 stage_id) { u32 action[] = { INTEL_GUC_ACTION_DEALLOCATE_DOORBELL, - ctx_index + stage_id }; return intel_guc_send(guc, action, ARRAY_SIZE(action)); } -static struct guc_context_desc *__get_context_desc(struct i915_guc_client *client) +static struct guc_stage_desc *__get_stage_desc(struct i915_guc_client *client) { - struct guc_context_desc *base = client->guc->ctx_pool_vaddr; + struct guc_stage_desc *base = client->guc->stage_desc_pool_vaddr; - return &base[client->ctx_index]; + return &base[client->stage_id]; } /* @@ -165,10 +165,10 @@ static struct guc_context_desc *__get_context_desc(struct i915_guc_client *clien static void __update_doorbell_desc(struct i915_guc_client *client, u16 new_id) { - struct guc_context_desc *desc; + struct guc_stage_desc *desc; /* Update the GuC's idea of the doorbell ID */ - desc = __get_context_desc(client); + desc = __get_stage_desc(client); desc->db_id = new_id; } @@ -194,7 +194,7 @@ static int __create_doorbell(struct i915_guc_client *client) doorbell->db_status = GUC_DOORBELL_ENABLED; doorbell->cookie = client->doorbell_cookie; - err = __guc_allocate_doorbell(client->guc, client->ctx_index); + err = __guc_allocate_doorbell(client->guc, client->stage_id); if (err) { doorbell->db_status = GUC_DOORBELL_DISABLED; doorbell->cookie = 0; @@ -220,7 +220,7 @@ static int __destroy_doorbell(struct i915_guc_client *client) if (wait_for_us(!(I915_READ(GEN8_DRBREGL(db_id)) & GEN8_DRB_VALID), 10)) WARN_ONCE(true, "Doorbell never became invalid after disable\n"); - return __guc_deallocate_doorbell(client->guc, client->ctx_index); + return __guc_deallocate_doorbell(client->guc, client->stage_id); } static int create_doorbell(struct i915_guc_client *client) @@ -301,34 +301,34 @@ static void guc_proc_desc_init(struct intel_guc *guc, desc->wq_base_addr = 0; desc->db_base_addr = 0; - desc->context_id = client->ctx_index; + desc->stage_id = client->stage_id; desc->wq_size_bytes = client->wq_size; desc->wq_status = WQ_STATUS_ACTIVE; desc->priority = client->priority; } /* - * Initialise/clear the context descriptor shared with the GuC firmware. + * Initialise/clear the stage descriptor shared with the GuC firmware. * * This descriptor tells the GuC where (in GGTT space) to find the important * data structures relating to this client (doorbell, process descriptor, * write queue, etc). */ -static void guc_ctx_desc_init(struct intel_guc *guc, - struct i915_guc_client *client) +static void guc_stage_desc_init(struct intel_guc *guc, + struct i915_guc_client *client) { struct drm_i915_private *dev_priv = guc_to_i915(guc); struct intel_engine_cs *engine; struct i915_gem_context *ctx = client->owner; - struct guc_context_desc *desc; + struct guc_stage_desc *desc; unsigned int tmp; u32 gfx_addr; - desc = __get_context_desc(client); + desc = __get_stage_desc(client); memset(desc, 0, sizeof(*desc)); - desc->attribute = GUC_CTX_DESC_ATTR_ACTIVE | GUC_CTX_DESC_ATTR_KERNEL; - desc->context_id = client->ctx_index; + desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE | GUC_STAGE_DESC_ATTR_KERNEL; + desc->stage_id = client->stage_id; desc->priority = client->priority; desc->db_id = client->doorbell_id; @@ -348,7 +348,7 @@ static void guc_ctx_desc_init(struct intel_guc *guc, break; /* XXX: continue? */ /* - * XXX: When this is a GUC_CTX_DESC_ATTR_KERNEL client (proxy + * XXX: When this is a GUC_STAGE_DESC_ATTR_KERNEL client (proxy * submission or, in other words, not using a direct submission * model) the KMD's LRCA is not used for any work submission. * Instead, the GuC uses the LRCA of the user mode context (see @@ -359,7 +359,10 @@ static void guc_ctx_desc_init(struct intel_guc *guc, /* The state page is after PPHWSP */ lrc->ring_lrca = guc_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE; - lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) | + + /* XXX: In direct submission, the GuC wants the HW context id + * here. In proxy submission, it wants the stage id */ + lrc->context_id = (client->stage_id << GUC_ELC_CTXID_OFFSET) | (guc_engine_id << GUC_ELC_ENGINE_OFFSET); lrc->ring_begin = guc_ggtt_offset(ce->ring->vma); @@ -390,12 +393,12 @@ static void guc_ctx_desc_init(struct intel_guc *guc, desc->desc_private = (uintptr_t)client; } -static void guc_ctx_desc_fini(struct intel_guc *guc, - struct i915_guc_client *client) +static void guc_stage_desc_fini(struct intel_guc *guc, + struct i915_guc_client *client) { - struct guc_context_desc *desc; + struct guc_stage_desc *desc; - desc = __get_context_desc(client); + desc = __get_stage_desc(client); memset(desc, 0, sizeof(*desc)); } @@ -863,7 +866,7 @@ static int guc_init_doorbell_hw(struct intel_guc *guc) ret = __create_doorbell(client); if (ret) { DRM_ERROR("Couldn't recreate client %u doorbell: %d\n", - client->ctx_index, ret); + client->stage_id, ret); return ret; } } @@ -913,12 +916,12 @@ guc_client_alloc(struct drm_i915_private *dev_priv, client->wq_size = GUC_WQ_SIZE; spin_lock_init(&client->wq_lock); - ret = ida_simple_get(&guc->ctx_ids, 0, GUC_MAX_GPU_CONTEXTS, + ret = ida_simple_get(&guc->stage_ids, 0, GUC_MAX_STAGE_DESCRIPTORS, GFP_KERNEL); if (ret < 0) goto err_client; - client->ctx_index = ret; + client->stage_id = ret; /* The first page is doorbell/proc_desc. Two followed pages are wq. */ vma = intel_guc_allocate_vma(guc, GUC_DB_SIZE + GUC_WQ_SIZE); @@ -950,14 +953,14 @@ guc_client_alloc(struct drm_i915_private *dev_priv, client->proc_desc_offset = (GUC_DB_SIZE / 2); guc_proc_desc_init(guc, client); - guc_ctx_desc_init(guc, client); + guc_stage_desc_init(guc, client); ret = create_doorbell(client); if (ret) goto err_vaddr; - DRM_DEBUG_DRIVER("new priority %u client %p for engine(s) 0x%x: ctx_index %u\n", - priority, client, client->engines, client->ctx_index); + DRM_DEBUG_DRIVER("new priority %u client %p for engine(s) 0x%x: stage_id %u\n", + priority, client, client->engines, client->stage_id); DRM_DEBUG_DRIVER("doorbell id %u, cacheline offset 0x%lx\n", client->doorbell_id, client->doorbell_offset); @@ -968,7 +971,7 @@ err_vaddr: err_vma: i915_vma_unpin_and_release(&client->vma); err_id: - ida_simple_remove(&guc->ctx_ids, client->ctx_index); + ida_simple_remove(&guc->stage_ids, client->stage_id); err_client: kfree(client); return ERR_PTR(ret); @@ -985,10 +988,10 @@ static void guc_client_free(struct i915_guc_client *client) * reset, so we cannot destroy the doorbell properly. Ignore the * error message for now */ destroy_doorbell(client); - guc_ctx_desc_fini(client->guc, client); + guc_stage_desc_fini(client->guc, client); i915_gem_object_unpin_map(client->vma->obj); i915_vma_unpin_and_release(&client->vma); - ida_simple_remove(&client->guc->ctx_ids, client->ctx_index); + ida_simple_remove(&client->guc->stage_ids, client->stage_id); kfree(client); } @@ -1000,7 +1003,7 @@ static void guc_policies_init(struct guc_policies *policies) policies->dpc_promote_time = 500000; policies->max_num_work_items = POLICY_MAX_NUM_WI; - for (p = 0; p < GUC_CTX_PRIORITY_NUM; p++) { + for (p = 0; p < GUC_CLIENT_PRIORITY_NUM; p++) { for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) { policy = &policies->policy[p][i]; @@ -1088,30 +1091,29 @@ static void guc_ads_destroy(struct intel_guc *guc) */ int i915_guc_submission_init(struct drm_i915_private *dev_priv) { - const size_t ctxsize = sizeof(struct guc_context_desc); - const size_t poolsize = GUC_MAX_GPU_CONTEXTS * ctxsize; - const size_t gemsize = round_up(poolsize, PAGE_SIZE); struct intel_guc *guc = &dev_priv->guc; struct i915_vma *vma; void *vaddr; int ret; - if (guc->ctx_pool) + if (guc->stage_desc_pool) return 0; - vma = intel_guc_allocate_vma(guc, gemsize); + vma = intel_guc_allocate_vma(guc, + PAGE_ALIGN(sizeof(struct guc_stage_desc) * + GUC_MAX_STAGE_DESCRIPTORS)); if (IS_ERR(vma)) return PTR_ERR(vma); - guc->ctx_pool = vma; + guc->stage_desc_pool = vma; - vaddr = i915_gem_object_pin_map(guc->ctx_pool->obj, I915_MAP_WB); + vaddr = i915_gem_object_pin_map(guc->stage_desc_pool->obj, I915_MAP_WB); if (IS_ERR(vaddr)) { ret = PTR_ERR(vaddr); goto err_vma; } - guc->ctx_pool_vaddr = vaddr; + guc->stage_desc_pool_vaddr = vaddr; ret = intel_guc_log_create(guc); if (ret < 0) @@ -1121,16 +1123,16 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv) if (ret < 0) goto err_log; - ida_init(&guc->ctx_ids); + ida_init(&guc->stage_ids); return 0; err_log: intel_guc_log_destroy(guc); err_vaddr: - i915_gem_object_unpin_map(guc->ctx_pool->obj); + i915_gem_object_unpin_map(guc->stage_desc_pool->obj); err_vma: - i915_vma_unpin_and_release(&guc->ctx_pool); + i915_vma_unpin_and_release(&guc->stage_desc_pool); return ret; } @@ -1138,11 +1140,11 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; - ida_destroy(&guc->ctx_ids); + ida_destroy(&guc->stage_ids); guc_ads_destroy(guc); intel_guc_log_destroy(guc); - i915_gem_object_unpin_map(guc->ctx_pool->obj); - i915_vma_unpin_and_release(&guc->ctx_pool); + i915_gem_object_unpin_map(guc->stage_desc_pool->obj); + i915_vma_unpin_and_release(&guc->stage_desc_pool); } static void guc_interrupts_capture(struct drm_i915_private *dev_priv) @@ -1198,7 +1200,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) if (!client) { client = guc_client_alloc(dev_priv, INTEL_INFO(dev_priv)->ring_mask, - GUC_CTX_PRIORITY_KMD_NORMAL, + GUC_CLIENT_PRIORITY_KMD_NORMAL, dev_priv->kernel_context); if (IS_ERR(client)) { DRM_ERROR("Failed to create GuC client for execbuf!\n"); |