From patchwork Fri Jul 22 15:15:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gordon X-Patchwork-Id: 9243783 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5CD7A60757 for ; Fri, 22 Jul 2016 15:16:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F07D27C0B for ; Fri, 22 Jul 2016 15:16:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 43C6D27FA5; Fri, 22 Jul 2016 15:16:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D190927C0B for ; Fri, 22 Jul 2016 15:16:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A80A96EBD9; Fri, 22 Jul 2016 15:16:18 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTP id 15C236EBD5 for ; Fri, 22 Jul 2016 15:16:14 +0000 (UTC) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 22 Jul 2016 08:15:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,405,1464678000"; d="scan'208";a="851326472" Received: from dsgordon-linux2.isw.intel.com ([10.102.226.88]) by orsmga003.jf.intel.com with ESMTP; 22 Jul 2016 08:15:53 -0700 From: Dave Gordon To: intel-gfx@lists.freedesktop.org Date: Fri, 22 Jul 2016 16:15:33 +0100 Message-Id: <1469200537-5279-4-git-send-email-david.s.gordon@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1469200537-5279-1-git-send-email-david.s.gordon@intel.com> References: <1469200537-5279-1-git-send-email-david.s.gordon@intel.com> Organization: Intel Corporation (UK) Ltd. - Co. Reg. #1134945 - Pipers Way, Swindon SN3 1RJ Subject: [Intel-gfx] [CI-Resend v2 3/6] drm/i915/guc: use a separate GuC client for each engine X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP When using a single GuC client for multiple engines, the i915 driver has to merge all work items into a single work queue, which the GuC firmware then demultiplexes into separate submission queues per engine. In theory, this could lead to the single queue becoming a bottleneck in which an excess of outstanding work for one or more engines might prevent work for an idle engine reaching the hardware. To reduce this risk, we can create one GuC client per engine. Each will have its own workqueue, to be used only for work targeting a single engine, so there will be no cross-engine contention for workqueue slots. Signed-off-by: Dave Gordon Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_debugfs.c | 25 ++++++++++++++++----- drivers/gpu/drm/i915/i915_guc_submission.c | 35 +++++++++++++++++++----------- drivers/gpu/drm/i915/intel_guc.h | 2 +- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9aa62c5..793b1d9 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2564,20 +2564,26 @@ static int i915_guc_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc guc; - struct i915_guc_client client = {}; + struct i915_guc_client *clients; struct intel_engine_cs *engine; + enum intel_engine_id id; u64 total = 0; if (!HAS_GUC_SCHED(dev_priv)) return 0; + clients = kcalloc(I915_NUM_ENGINES, sizeof(*clients), GFP_KERNEL); + if (clients == NULL) + return -ENOMEM; + if (mutex_lock_interruptible(&dev->struct_mutex)) - return 0; + goto done; /* Take a local copy of the GuC data, so we can dump it at leisure */ guc = dev_priv->guc; - if (guc.execbuf_client) - client = *guc.execbuf_client; + for_each_engine_id(engine, dev_priv, id) + if (guc.exec_clients[id]) + clients[id] = *guc.exec_clients[id]; mutex_unlock(&dev->struct_mutex); @@ -2600,11 +2606,18 @@ static int i915_guc_info(struct seq_file *m, void *data) } seq_printf(m, "\t%s: %llu\n", "Total", total); - seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client); - i915_guc_client_info(m, dev_priv, &client); + for_each_engine_id(engine, dev_priv, id) { + seq_printf(m, "\nGuC exec_client[%d] @ %p:\n", + id, guc.exec_clients[id]); + if (guc.exec_clients[id]) + i915_guc_client_info(m, dev_priv, &clients[id]); + } /* Add more as required ... */ +done: + kfree(clients); + return 0; } diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 816bdca..9999797 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -434,7 +434,9 @@ static void guc_fini_ctx_desc(struct intel_guc *guc, int i915_guc_wq_check_space(struct drm_i915_gem_request *request) { const size_t wqi_size = sizeof(struct guc_wq_item); - struct i915_guc_client *gc = request->i915->guc.execbuf_client; + enum intel_engine_id engine_id = request->engine->id; + struct intel_guc *guc = &request->i915->guc; + struct i915_guc_client *gc = guc->exec_clients[engine_id]; struct guc_process_desc *desc; u32 freespace; @@ -589,7 +591,7 @@ int i915_guc_submit(struct drm_i915_gem_request *rq) { unsigned int engine_id = rq->engine->id; struct intel_guc *guc = &rq->i915->guc; - struct i915_guc_client *client = guc->execbuf_client; + struct i915_guc_client *client = guc->exec_clients[engine_id]; int b_ret; guc_add_workqueue_item(client, rq); @@ -723,7 +725,7 @@ static bool guc_doorbell_check(struct intel_guc *guc, uint16_t db_id) */ static void guc_init_doorbell_hw(struct intel_guc *guc) { - struct i915_guc_client *client = guc->execbuf_client; + struct i915_guc_client *client = guc->exec_clients[RCS]; uint16_t db_id; int i, err; @@ -1004,17 +1006,21 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; struct i915_guc_client *client; + struct intel_engine_cs *engine; - /* client for execbuf submission */ - client = guc_client_alloc(dev_priv, - GUC_CTX_PRIORITY_KMD_NORMAL, - dev_priv->kernel_context); - if (!client) { - DRM_ERROR("Failed to create execbuf guc_client\n"); - return -ENOMEM; + for_each_engine(engine, dev_priv) { + /* client for execbuf submission */ + client = guc_client_alloc(dev_priv, + GUC_CTX_PRIORITY_KMD_NORMAL, + dev_priv->kernel_context); + if (!client) { + DRM_ERROR("Failed to create GuC client(s)\n"); + return -ENOMEM; + } + + guc->exec_clients[engine->id] = client; } - guc->execbuf_client = client; host2guc_sample_forcewake(guc, client); guc_init_doorbell_hw(guc); @@ -1024,9 +1030,12 @@ 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; + struct intel_engine_cs *engine; - guc_client_free(dev_priv, guc->execbuf_client); - guc->execbuf_client = NULL; + for_each_engine(engine, dev_priv) { + guc_client_free(dev_priv, guc->exec_clients[engine->id]); + guc->exec_clients[engine->id] = NULL; + } } void i915_guc_submission_fini(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 3e3e743..7b4cc4d 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -132,7 +132,7 @@ struct intel_guc { struct drm_i915_gem_object *ctx_pool_obj; struct ida ctx_ids; - struct i915_guc_client *execbuf_client; + struct i915_guc_client *exec_clients[I915_NUM_ENGINES]; DECLARE_BITMAP(doorbell_bitmap, GUC_MAX_DOORBELLS); uint32_t db_cacheline; /* Cyclic counter mod pagesize */