From patchwork Thu Feb 23 19:14:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micha=C5=82_Winiarski?= X-Patchwork-Id: 9588855 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 07E1A60578 for ; Thu, 23 Feb 2017 19:15:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E919A28739 for ; Thu, 23 Feb 2017 19:15:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCC81287CE; Thu, 23 Feb 2017 19:15:10 +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]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 318B728739 for ; Thu, 23 Feb 2017 19:15:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B8FDA6EAEE; Thu, 23 Feb 2017 19:15:09 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 11B226EB09 for ; Thu, 23 Feb 2017 19:15:08 +0000 (UTC) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Feb 2017 11:15:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.35,198,1484035200"; d="scan'208"; a="1114783490" Received: from irsmsx102.ger.corp.intel.com ([163.33.3.155]) by fmsmga001.fm.intel.com with ESMTP; 23 Feb 2017 11:15:02 -0800 Received: from mwiniars-main.igk.intel.com (172.28.171.152) by IRSMSX102.ger.corp.intel.com (163.33.3.155) with Microsoft SMTP Server id 14.3.248.2; Thu, 23 Feb 2017 19:15:01 +0000 From: =?UTF-8?q?Micha=C5=82=20Winiarski?= To: Date: Thu, 23 Feb 2017 20:14:17 +0100 Message-ID: <20170223191421.4502-3-michal.winiarski@intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170223190833.2888-1-michal.winiarski@intel.com> References: <20170223190833.2888-1-michal.winiarski@intel.com> MIME-Version: 1.0 X-Originating-IP: [172.28.171.152] Cc: Dave Gordon Subject: [Intel-gfx] [RFC 07/11] drm/i915/guc: Add a second client, to be used for preemption 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: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Dave Gordon This second client is created with priority KMD_HIGH, and marked as preemptive. v2: Rebase, cleanup, use an array for the second client. Signed-off-by: Dave Gordon Signed-off-by: MichaƂ Winiarski --- drivers/gpu/drm/i915/i915_debugfs.c | 8 +-- drivers/gpu/drm/i915/i915_guc_submission.c | 86 ++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_uc.h | 9 +++- 3 files changed, 71 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1a28b52..10490bf 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2514,7 +2514,7 @@ static int i915_guc_info(struct seq_file *m, void *data) enum intel_engine_id id; u64 total; - if (!guc->execbuf_client) { + if (!guc->client[NORMAL]) { seq_printf(m, "GuC submission %s\n", HAS_GUC_SCHED(dev_priv) ? "disabled" : @@ -2542,8 +2542,10 @@ 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, guc->execbuf_client); + seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->client[NORMAL]); + i915_guc_client_info(m, dev_priv, guc->client[NORMAL]); + seq_printf(m, "\nGuC preempt client @ %p:\n", guc->client[PREEMPT]); + i915_guc_client_info(m, dev_priv, guc->client[PREEMPT]); i915_guc_log_info(m, dev_priv); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 3080735..2a658b9 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -247,6 +247,8 @@ static void guc_ctx_desc_init(struct intel_guc *guc, memset(&desc, 0, sizeof(desc)); desc.attribute = GUC_CTX_DESC_ATTR_ACTIVE | GUC_CTX_DESC_ATTR_KERNEL; + if (client->priority <= GUC_CTX_PRIORITY_HIGH) + desc.attribute |= GUC_CTX_DESC_ATTR_PREEMPT; desc.context_id = client->ctx_index; desc.priority = client->priority; desc.db_id = client->doorbell_id; @@ -344,7 +346,7 @@ static void guc_ctx_desc_fini(struct intel_guc *guc, 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 i915_guc_client *client = request->i915->guc.client[NORMAL]; struct guc_process_desc *desc = client->vaddr + client->proc_desc_offset; u32 freespace; @@ -368,7 +370,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request) void i915_guc_wq_unreserve(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 i915_guc_client *client = request->i915->guc.client[NORMAL]; GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size); @@ -518,7 +520,7 @@ static void __i915_guc_submit(struct drm_i915_gem_request *rq) struct intel_engine_cs *engine = rq->engine; unsigned int engine_id = engine->id; struct intel_guc *guc = &rq->i915->guc; - struct i915_guc_client *client = guc->execbuf_client; + struct i915_guc_client *client = guc->client[NORMAL]; int b_ret; spin_lock(&client->wq_lock); @@ -747,8 +749,8 @@ struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size) } static void -guc_client_free(struct drm_i915_private *dev_priv, - struct i915_guc_client *client) +__guc_client_free(struct drm_i915_private *dev_priv, + struct i915_guc_client *client) { struct intel_guc *guc = &dev_priv->guc; @@ -805,7 +807,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->client[NORMAL]; uint16_t db_id; int i, err; @@ -836,7 +838,7 @@ static void guc_init_doorbell_hw(struct intel_guc *guc) } /** - * guc_client_alloc() - Allocate an i915_guc_client + * __guc_client_alloc() - Allocate an i915_guc_client * @dev_priv: driver private data structure * @priority: four levels priority _CRITICAL, _HIGH, _NORMAL and _LOW * The kernel client to replace ExecList submission is created with @@ -845,8 +847,8 @@ static void guc_init_doorbell_hw(struct intel_guc *guc) * Return: An i915_guc_client object if success, else NULL. */ static struct i915_guc_client * -guc_client_alloc(struct drm_i915_private *dev_priv, - uint32_t priority) +__guc_client_alloc(struct drm_i915_private *dev_priv, + uint32_t priority) { struct i915_guc_client *client; struct intel_guc *guc = &dev_priv->guc; @@ -910,7 +912,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv, guc_ctx_desc_init(guc, client); /* For runtime client allocation we need to enable the doorbell. Not - * required yet for the static execbuf_client as this special kernel + * required yet for the static client as this special kernel * client is enabled from i915_guc_submission_enable(). * * guc_update_doorbell_id(guc, client, db_id); @@ -924,7 +926,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv, return client; err: - guc_client_free(dev_priv, client); + __guc_client_free(dev_priv, client); return NULL; } @@ -1021,6 +1023,45 @@ static void guc_addon_create(struct intel_guc *guc) kunmap(page); } +static void guc_free_clients(struct drm_i915_private *dev_priv) +{ + struct intel_guc *guc = &dev_priv->guc; + struct i915_guc_client *client; + + client = fetch_and_zero(&guc->client[NORMAL]); + if (client) + __guc_client_free(dev_priv, client); + + client = fetch_and_zero(&guc->client[PREEMPT]); + if (client) + __guc_client_free(dev_priv, client); +} + +static int guc_alloc_clients(struct drm_i915_private *dev_priv) +{ + struct intel_guc *guc = &dev_priv->guc; + + guc->client[NORMAL] = __guc_client_alloc(dev_priv, + GUC_CTX_PRIORITY_KMD_NORMAL); + if (!guc->client[NORMAL]) { + DRM_ERROR("Failed to create GuC client for execbuf!\n"); + goto err; + } + + guc->client[PREEMPT] = __guc_client_alloc(dev_priv, + GUC_CTX_PRIORITY_KMD_HIGH); + if (!guc->client[PREEMPT]) { + DRM_ERROR("Failed to create GuC client for execbuf!\n"); + goto err; + } + + return 0; + +err: + guc_free_clients(dev_priv); + return -ENOMEM; +} + /* * Set up the memory resources to be shared with the GuC. At this point, * we require just one object that can be mapped through the GGTT. @@ -1055,18 +1096,12 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv) intel_guc_log_create(guc); guc_addon_create(guc); - guc->execbuf_client = guc_client_alloc(dev_priv, - GUC_CTX_PRIORITY_KMD_NORMAL); - if (!guc->execbuf_client) { - DRM_ERROR("Failed to create GuC client for execbuf!\n"); - goto err; + if (guc_alloc_clients(dev_priv) != 0) { + i915_guc_submission_fini(dev_priv); + return -ENOMEM; } return 0; - -err: - i915_guc_submission_fini(dev_priv); - return -ENOMEM; } static void guc_reset_wq(struct i915_guc_client *client) @@ -1083,7 +1118,7 @@ static void guc_reset_wq(struct i915_guc_client *client) int i915_guc_submission_enable(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; - struct i915_guc_client *client = guc->execbuf_client; + struct i915_guc_client *client = guc->client[NORMAL]; struct intel_engine_cs *engine; enum intel_engine_id id; @@ -1129,7 +1164,7 @@ void i915_guc_submission_disable(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; - if (!guc->execbuf_client) + if (!guc->client[NORMAL]) return; /* Revert back to manual ELSP submission */ @@ -1139,13 +1174,8 @@ void i915_guc_submission_disable(struct drm_i915_private *dev_priv) void i915_guc_submission_fini(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; - struct i915_guc_client *client; - - client = fetch_and_zero(&guc->execbuf_client); - if (!client) - return; - guc_client_free(dev_priv, client); + guc_free_clients(dev_priv); i915_vma_unpin_and_release(&guc->ads_vma); i915_vma_unpin_and_release(&guc->log.vma); diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index d74f4d3..9dcd8fa 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -146,6 +146,13 @@ struct intel_guc_log { u32 flush_count[GUC_MAX_LOG_BUFFER]; }; +#define I915_GUC_NUM_CLIENTS 2 + +enum i915_guc_client_id { + NORMAL = 0, + PREEMPT +}; + struct intel_guc { struct intel_uc_fw fw; struct intel_guc_log log; @@ -157,7 +164,7 @@ struct intel_guc { struct i915_vma *ctx_pool_vma; struct ida ctx_ids; - struct i915_guc_client *execbuf_client; + struct i915_guc_client *client[I915_GUC_NUM_CLIENTS]; DECLARE_BITMAP(doorbell_bitmap, GUC_MAX_DOORBELLS); uint32_t db_cacheline; /* Cyclic counter mod pagesize */