Now that we have an upper bound on the number of work items being sent
to GuC, we can remove the reservation.

v2: Multiply by number of engines in compile time assert (Daniele)
v3: Comment on reasoning behind the compile time assert (Chris)

Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospu...@intel.com>
Cc: Jeff McGee <jeff.mc...@intel.com>
Cc: Michal Wajdeczko <michal.wajdec...@intel.com>
Cc: Oscar Mateo <oscar.ma...@intel.com>
Signed-off-by: Michał Winiarski <michal.winiar...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c        |  2 -
 drivers/gpu/drm/i915/i915_guc_submission.c | 89 +++++-------------------------
 drivers/gpu/drm/i915/intel_lrc.c           | 25 +--------
 drivers/gpu/drm/i915/intel_uc.h            |  8 ---
 4 files changed, 17 insertions(+), 107 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 0969b8d..83366a4 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2481,8 +2481,6 @@ static void i915_guc_client_info(struct seq_file *m,
        seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n",
                client->wq_size, client->wq_offset, client->wq_tail);
 
-       seq_printf(m, "\tWork queue full: %u\n", client->no_wq_space);
-
        for_each_engine(engine, dev_priv, id) {
                u64 submissions = client->submissions[id];
                tot += submissions;
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c 
b/drivers/gpu/drm/i915/i915_guc_submission.c
index 2a0c3161..66d8eaf 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -406,63 +406,6 @@ static void guc_stage_desc_fini(struct intel_guc *guc,
        memset(desc, 0, sizeof(*desc));
 }
 
-/**
- * i915_guc_wq_reserve() - reserve space in the GuC's workqueue
- * @request:   request associated with the commands
- *
- * Return:     0 if space is available
- *             -EAGAIN if space is not currently available
- *
- * This function must be called (and must return 0) before a request
- * is submitted to the GuC via i915_guc_submit() below. Once a result
- * of 0 has been returned, it must be balanced by a corresponding
- * call to submit().
- *
- * Reservation allows the caller to determine in advance that space
- * will be available for the next submission before committing resources
- * to it, and helps avoid late failures with complicated recovery paths.
- */
-int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
-{
-       const size_t wqi_size = sizeof(struct guc_wq_item);
-       struct i915_guc_client *client = request->i915->guc.execbuf_client;
-       struct guc_process_desc *desc = __get_process_desc(client);
-       u32 freespace;
-       int ret;
-
-       spin_lock_irq(&client->wq_lock);
-       freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size);
-       freespace -= client->wq_rsvd;
-       if (likely(freespace >= wqi_size)) {
-               client->wq_rsvd += wqi_size;
-               ret = 0;
-       } else {
-               client->no_wq_space++;
-               ret = -EAGAIN;
-       }
-       spin_unlock_irq(&client->wq_lock);
-
-       return ret;
-}
-
-static void guc_client_update_wq_rsvd(struct i915_guc_client *client, int size)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&client->wq_lock, flags);
-       client->wq_rsvd += size;
-       spin_unlock_irqrestore(&client->wq_lock, flags);
-}
-
-void i915_guc_wq_unreserve(struct drm_i915_gem_request *request)
-{
-       const int wqi_size = sizeof(struct guc_wq_item);
-       struct i915_guc_client *client = request->i915->guc.execbuf_client;
-
-       GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size);
-       guc_client_update_wq_rsvd(client, -wqi_size);
-}
-
 /* Construct a Work Item and append it to the GuC's Work Queue */
 static void guc_wq_item_append(struct i915_guc_client *client,
                               struct drm_i915_gem_request *rq)
@@ -475,7 +418,7 @@ static void guc_wq_item_append(struct i915_guc_client 
*client,
        struct guc_wq_item *wqi;
        u32 freespace, tail, wq_off;
 
-       /* Free space is guaranteed, see i915_guc_wq_reserve() above */
+       /* Free space is guaranteed */
        freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size);
        GEM_BUG_ON(freespace < wqi_size);
 
@@ -581,14 +524,6 @@ static int guc_ring_doorbell(struct i915_guc_client 
*client)
  * i915_guc_submit() - Submit commands through GuC
  * @rq:                request associated with the commands
  *
- * The caller must have already called i915_guc_wq_reserve() above with
- * a result of 0 (success), guaranteeing that there is space in the work
- * queue for the new request, so enqueuing the item cannot fail.
- *
- * Bad Things Will Happen if the caller violates this protocol e.g. calls
- * submit() when _reserve() says there's no space, or calls _submit()
- * a different number of times from (successful) calls to _reserve().
- *
  * The only error here arises if the doorbell hardware isn't functioning
  * as expected, which really shouln't happen.
  */
@@ -691,7 +626,6 @@ static void i915_guc_dequeue(struct intel_engine_cs *engine)
                        trace_i915_gem_request_in(rq, port_index(port, engine));
                        last = rq;
                        submit = true;
-                       i915_guc_wq_unreserve(rq);
                }
 
                rb = rb_next(rb);
@@ -1216,6 +1150,19 @@ int i915_guc_submission_enable(struct drm_i915_private 
*dev_priv)
        enum intel_engine_id id;
        int err;
 
+       /*
+        * We're using GuC work items for submitting work through GuC. Since
+        * we're coalescing multiple requests from a single context into a
+        * single work item prior to assigning it to execlist_port, we can
+        * never have more work items than the total number of ports (for all
+        * engines). The GuC firmware is controlling the HEAD of work queue,
+        * and it is guaranteed that it will remove the work item from the
+        * queue before our request is completed.
+        */
+       BUILD_BUG_ON(ARRAY_SIZE(engine->execlist_port) *
+                    sizeof(struct guc_wq_item) *
+                    I915_NUM_ENGINES > GUC_WQ_SIZE);
+
        if (!client) {
                client = guc_client_alloc(dev_priv,
                                          INTEL_INFO(dev_priv)->ring_mask,
@@ -1243,8 +1190,6 @@ int i915_guc_submission_enable(struct drm_i915_private 
*dev_priv)
        guc_interrupts_capture(dev_priv);
 
        for_each_engine(engine, dev_priv, id) {
-               const int wqi_size = sizeof(struct guc_wq_item);
-               struct drm_i915_gem_request *rq;
                struct execlist_port *port = engine->execlist_port;
                int n;
 
@@ -1256,12 +1201,6 @@ int i915_guc_submission_enable(struct drm_i915_private 
*dev_priv)
                engine->irq_tasklet.func = i915_guc_irq_handler;
                clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
 
-               /* Replay the current set of previously submitted requests */
-               spin_lock_irq(&engine->timeline->lock);
-               list_for_each_entry(rq, &engine->timeline->requests, link)
-                       guc_client_update_wq_rsvd(client, wqi_size);
-               spin_unlock_irq(&engine->timeline->lock);
-
                for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {
                        if (!port_isset(&port[n]))
                                break;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 014b30a..5d4f23c 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -913,27 +913,14 @@ static int execlists_request_alloc(struct 
drm_i915_gem_request *request)
         */
        request->reserved_space += EXECLISTS_REQUEST_SIZE;
 
-       if (i915.enable_guc_submission) {
-               /*
-                * Check that the GuC has space for the request before
-                * going any further, as the i915_add_request() call
-                * later on mustn't fail ...
-                */
-               ret = i915_guc_wq_reserve(request);
-               if (ret)
-                       goto err;
-       }
-
        cs = intel_ring_begin(request, 0);
-       if (IS_ERR(cs)) {
-               ret = PTR_ERR(cs);
-               goto err_unreserve;
-       }
+       if (IS_ERR(cs))
+               return PTR_ERR(cs);
 
        if (!ce->initialised) {
                ret = engine->init_context(request);
                if (ret)
-                       goto err_unreserve;
+                       return ret;
 
                ce->initialised = true;
        }
@@ -947,12 +934,6 @@ static int execlists_request_alloc(struct 
drm_i915_gem_request *request)
 
        request->reserved_space -= EXECLISTS_REQUEST_SIZE;
        return 0;
-
-err_unreserve:
-       if (i915.enable_guc_submission)
-               i915_guc_wq_unreserve(request);
-err:
-       return ret;
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 930f2e1..b86f866 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -55,10 +55,6 @@ struct drm_i915_gem_request;
  *
  * We also keep a few statistics on failures. Ideally, these should all
  * be zero!
- *   no_wq_space: times that the submission pre-check found no space was
- *                available in the work queue (note, the queue is shared,
- *                not per-engine). It is OK for this to be nonzero, but
- *                it should not be huge!
  */
 struct i915_guc_client {
        struct i915_vma *vma;
@@ -79,8 +75,6 @@ struct i915_guc_client {
        uint32_t wq_offset;
        uint32_t wq_size;
        uint32_t wq_tail;
-       uint32_t wq_rsvd;
-       uint32_t no_wq_space;
 
        /* Per-engine counts of GuC submissions */
        uint64_t submissions[I915_NUM_ENGINES];
@@ -242,8 +236,6 @@ u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv);
 /* i915_guc_submission.c */
 int i915_guc_submission_init(struct drm_i915_private *dev_priv);
 int i915_guc_submission_enable(struct drm_i915_private *dev_priv);
-int i915_guc_wq_reserve(struct drm_i915_gem_request *rq);
-void i915_guc_wq_unreserve(struct drm_i915_gem_request *request);
 void i915_guc_submission_disable(struct drm_i915_private *dev_priv);
 void i915_guc_submission_fini(struct drm_i915_private *dev_priv);
 struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to