From patchwork Tue Jul 19 12:59:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gordon X-Patchwork-Id: 9237101 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 BB22F6075D for ; Tue, 19 Jul 2016 12:59:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ACA5E26D08 for ; Tue, 19 Jul 2016 12:59:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A097226D19; Tue, 19 Jul 2016 12:59:55 +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 394F426B4A for ; Tue, 19 Jul 2016 12:59:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B7A946E6A4; Tue, 19 Jul 2016 12:59:48 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id F37126E3A7 for ; Tue, 19 Jul 2016 12:59:26 +0000 (UTC) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP; 19 Jul 2016 05:59:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.28,389,1464678000"; d="scan'208"; a="1024757465" Received: from dsgordon-linux2.isw.intel.com ([10.102.226.88]) by fmsmga002.fm.intel.com with ESMTP; 19 Jul 2016 05:59:26 -0700 From: Dave Gordon To: intel-gfx@lists.freedesktop.org Date: Tue, 19 Jul 2016 13:59:15 +0100 Message-Id: <1468933157-22412-3-git-send-email-david.s.gordon@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1468933157-22412-1-git-send-email-david.s.gordon@intel.com> References: <1468933157-22412-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] [PATCH 3/5] 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 90aef45..5cbb8ef 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2570,20 +2570,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); @@ -2606,11 +2612,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 dc5f485..b0f9945 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 */