aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Gordon <david.s.gordon@intel.com>2016-05-13 10:36:32 -0400
committerTvrtko Ursulin <tvrtko.ursulin@intel.com>2016-05-23 09:21:53 -0400
commit7c2c270d27dd4e52529deee9814493c27f956218 (patch)
tree5a90f236ceb22a59008471512a9ac0827e9217d3
parentfce91f22ff31601a03bdeb5f09b525b035021259 (diff)
drm/i915/guc: pass request (not client) to i915_guc_{wq_check_space, submit}()
The knowledge of how to derive the relevant client from the request should be localised within i915_guc_submission.c; the LRC code shouldn't have to know about the internal details of the GuC submission process. And all the information the GuC code needs should be encapsulated in (or reachable from) the request. v2: GEM_BUG_ON() for bad GuC client (Tvrtko Ursulin). Add/update kerneldoc explaining check_space/submit protocol Signed-off-by: Dave Gordon <david.s.gordon@intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_guc_submission.c46
-rw-r--r--drivers/gpu/drm/i915/intel_guc.h5
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c9
3 files changed, 42 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 916cd6778cf3..87cb7396ff93 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -450,14 +450,30 @@ static void guc_fini_ctx_desc(struct intel_guc *guc,
450 sizeof(desc) * client->ctx_index); 450 sizeof(desc) * client->ctx_index);
451} 451}
452 452
453int i915_guc_wq_check_space(struct i915_guc_client *gc) 453/**
454 * i915_guc_wq_check_space() - check that the GuC can accept a request
455 * @request: request associated with the commands
456 *
457 * Return: 0 if space is available
458 * -EAGAIN if space is not currently available
459 *
460 * This function must be called (and must return 0) before a request
461 * is submitted to the GuC via i915_guc_submit() below. Once a result
462 * of 0 has been returned, it remains valid until (but only until)
463 * the next call to submit().
464 *
465 * This precheck allows the caller to determine in advance that space
466 * will be available for the next submission before committing resources
467 * to it, and helps avoid late failures with complicated recovery paths.
468 */
469int i915_guc_wq_check_space(struct drm_i915_gem_request *request)
454{ 470{
471 const size_t size = sizeof(struct guc_wq_item);
472 struct i915_guc_client *gc = request->i915->guc.execbuf_client;
455 struct guc_process_desc *desc; 473 struct guc_process_desc *desc;
456 u32 size = sizeof(struct guc_wq_item);
457 int ret = -ETIMEDOUT, timeout_counter = 200; 474 int ret = -ETIMEDOUT, timeout_counter = 200;
458 475
459 if (!gc) 476 GEM_BUG_ON(gc == NULL);
460 return 0;
461 477
462 desc = gc->client_base + gc->proc_desc_offset; 478 desc = gc->client_base + gc->proc_desc_offset;
463 479
@@ -531,16 +547,28 @@ static int guc_add_workqueue_item(struct i915_guc_client *gc,
531 547
532/** 548/**
533 * i915_guc_submit() - Submit commands through GuC 549 * i915_guc_submit() - Submit commands through GuC
534 * @client: the guc client where commands will go through
535 * @rq: request associated with the commands 550 * @rq: request associated with the commands
536 * 551 *
537 * Return: 0 if succeed 552 * Return: 0 on success, otherwise an errno.
553 * (Note: nonzero really shouldn't happen!)
554 *
555 * The caller must have already called i915_guc_wq_check_space() above
556 * with a result of 0 (success) since the last request submission. This
557 * guarantees that there is space in the work queue for the new request,
558 * so enqueuing the item cannot fail.
559 *
560 * Bad Things Will Happen if the caller violates this protocol e.g. calls
561 * submit() when check() says there's no space, or calls submit() multiple
562 * times with no intervening check().
563 *
564 * The only error here arises if the doorbell hardware isn't functioning
565 * as expected, which really shouln't happen.
538 */ 566 */
539int i915_guc_submit(struct i915_guc_client *client, 567int i915_guc_submit(struct drm_i915_gem_request *rq)
540 struct drm_i915_gem_request *rq)
541{ 568{
542 struct intel_guc *guc = client->guc;
543 unsigned int engine_id = rq->engine->guc_id; 569 unsigned int engine_id = rq->engine->guc_id;
570 struct intel_guc *guc = &rq->i915->guc;
571 struct i915_guc_client *client = guc->execbuf_client;
544 int q_ret, b_ret; 572 int q_ret, b_ret;
545 573
546 q_ret = guc_add_workqueue_item(client, rq); 574 q_ret = guc_add_workqueue_item(client, rq);
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 3984136584ea..91f315cf073b 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -148,10 +148,9 @@ extern int intel_guc_resume(struct drm_device *dev);
148/* i915_guc_submission.c */ 148/* i915_guc_submission.c */
149int i915_guc_submission_init(struct drm_device *dev); 149int i915_guc_submission_init(struct drm_device *dev);
150int i915_guc_submission_enable(struct drm_device *dev); 150int i915_guc_submission_enable(struct drm_device *dev);
151int i915_guc_submit(struct i915_guc_client *client, 151int i915_guc_wq_check_space(struct drm_i915_gem_request *rq);
152 struct drm_i915_gem_request *rq); 152int i915_guc_submit(struct drm_i915_gem_request *rq);
153void i915_guc_submission_disable(struct drm_device *dev); 153void i915_guc_submission_disable(struct drm_device *dev);
154void i915_guc_submission_fini(struct drm_device *dev); 154void i915_guc_submission_fini(struct drm_device *dev);
155int i915_guc_wq_check_space(struct i915_guc_client *client);
156 155
157#endif 156#endif
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index affca6d5ce7e..0d1772a122fe 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -696,9 +696,7 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request
696 * going any further, as the i915_add_request() call 696 * going any further, as the i915_add_request() call
697 * later on mustn't fail ... 697 * later on mustn't fail ...
698 */ 698 */
699 struct intel_guc *guc = &request->i915->guc; 699 ret = i915_guc_wq_check_space(request);
700
701 ret = i915_guc_wq_check_space(guc->execbuf_client);
702 if (ret) 700 if (ret)
703 return ret; 701 return ret;
704 } 702 }
@@ -747,7 +745,6 @@ static int
747intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) 745intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request)
748{ 746{
749 struct intel_ringbuffer *ringbuf = request->ringbuf; 747 struct intel_ringbuffer *ringbuf = request->ringbuf;
750 struct drm_i915_private *dev_priv = request->i915;
751 struct intel_engine_cs *engine = request->engine; 748 struct intel_engine_cs *engine = request->engine;
752 749
753 intel_logical_ring_advance(ringbuf); 750 intel_logical_ring_advance(ringbuf);
@@ -775,8 +772,8 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request)
775 request->previous_context = engine->last_context; 772 request->previous_context = engine->last_context;
776 engine->last_context = request->ctx; 773 engine->last_context = request->ctx;
777 774
778 if (dev_priv->guc.execbuf_client) 775 if (i915.enable_guc_submission)
779 i915_guc_submit(dev_priv->guc.execbuf_client, request); 776 i915_guc_submit(request);
780 else 777 else
781 execlists_context_queue(request); 778 execlists_context_queue(request);
782 779