From patchwork Sat Jul 2 18:51:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: akash.goel@intel.com X-Patchwork-Id: 9210997 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 1739160571 for ; Sat, 2 Jul 2016 18:38:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0827D283F6 for ; Sat, 2 Jul 2016 18:38:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F124328544; Sat, 2 Jul 2016 18:38:36 +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 94DF2283F6 for ; Sat, 2 Jul 2016 18:38:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1EAD96E295; Sat, 2 Jul 2016 18:38:36 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 666C56E29C for ; Sat, 2 Jul 2016 18:38:34 +0000 (UTC) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 02 Jul 2016 11:38:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.26,564,1459839600"; d="scan'208"; a="1014206519" Received: from akashgoe-desktop.iind.intel.com ([10.223.82.36]) by fmsmga002.fm.intel.com with ESMTP; 02 Jul 2016 11:38:32 -0700 From: akash.goel@intel.com To: intel-gfx@lists.freedesktop.org Date: Sun, 3 Jul 2016 00:21:28 +0530 Message-Id: <1467485491-17247-12-git-send-email-akash.goel@intel.com> X-Mailer: git-send-email 1.9.2 In-Reply-To: <1467485491-17247-1-git-send-email-akash.goel@intel.com> References: <1467485491-17247-1-git-send-email-akash.goel@intel.com> Cc: Akash Goel Subject: [Intel-gfx] [PATCH 11/14] drm/i915: Use uncached(WC) mapping for acessing the GuC log buffer 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 From: Akash Goel Host needs to sample the GuC log buffer on every flush interrupt from GuC. To ensure that we always get the up-to-date data from log buffer, its better to access the buffer through an uncached CPU mapping. Also the way buffer is accessed from GuC & Host side, manually doing cache flush may not be effective always if cached CPU mapping is used. Since the data to be read is less than 50 KB, there would not be any performance implications. Signed-off-by: Akash Goel --- drivers/gpu/drm/i915/i915_guc_submission.c | 53 +++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_guc.h | 1 + 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index ec68a6d..4d76588 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -874,7 +874,7 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all) u32 num_pages_to_copy; int i; - if (!guc->log.obj) + if (!guc->log.obj || !guc->log.buf_addr) return; num_pages_to_copy = guc->log.obj->base.size / PAGE_SIZE; @@ -884,8 +884,7 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all) if (!capture_all) num_pages_to_copy -= (GUC_LOG_CRASH_PAGES + 1); - log_buffer_state = src_ptr = - kmap_atomic(i915_gem_object_get_page(guc->log.obj, 0)); + log_buffer_state = src_ptr = guc->log.buf_addr; /* Get the pointer to local buffer to store the logs */ dst_ptr = log_buffer_copy_state = guc_get_write_buffer(guc); @@ -906,8 +905,6 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all) log_buffer_copy_state++; } - /* FIXME: invalidate/flush for log buffer needed */ - /* Update the read pointer in the shared log buffer */ log_buffer_state->read_ptr = log_buffer_state->sampled_write_ptr; @@ -917,14 +914,11 @@ static void guc_read_update_log_buffer(struct drm_device *dev, bool capture_all) log_buffer_state++; } - kunmap_atomic(src_ptr); - /* Now copy the actual logs */ for (i=1; (i < num_pages_to_copy) && dst_ptr; i++) { dst_ptr += PAGE_SIZE; - src_ptr = kmap_atomic(i915_gem_object_get_page(guc->log.obj, i)); + src_ptr += PAGE_SIZE; memcpy(dst_ptr, src_ptr, PAGE_SIZE); - kunmap_atomic(src_ptr); } } @@ -1016,7 +1010,7 @@ static int guc_create_log_relay_file(struct intel_guc *guc) /* Keep the size of sub buffers same as shared log buffer */ subbuf_size = guc->log.obj->base.size; - n_subbufs = i915.guc_log_buffer_nr + n_subbufs = i915.guc_log_buffer_nr; guc_log_relay_chan = relay_open("guc_log", log_dir, subbuf_size, n_subbufs, &relay_callbacks, dev); @@ -1051,6 +1045,7 @@ static int guc_log_late_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_guc *guc = &dev_priv->guc; + void *vaddr; int ret; lockdep_assert_held(&dev->struct_mutex); @@ -1061,9 +1056,26 @@ static int guc_log_late_setup(struct drm_device *dev) if (WARN_ON(guc->log.relay_chan)) return -EINVAL; + /* If log_level was set as -1 at boot time, then vmalloc mapping would + * not have been created for the log buffer, so create one now. + */ + if (!guc->log.buf_addr) { + vaddr = i915_gem_object_pin_map(guc->log.obj, true); + if (IS_ERR(vaddr)) { + ret = PTR_ERR(vaddr); + DRM_DEBUG_DRIVER("Couldn't map log buffer %d\n", ret); + goto err; + } + guc->log.buf_addr = vaddr; + } + + ret = guc_create_log_relay_file(guc); - if (ret) + if (ret) { + guc->log.buf_addr = NULL; + i915_gem_object_unpin_map(guc->log.obj); goto err; + } return 0; err: @@ -1098,6 +1110,25 @@ static void guc_create_log(struct intel_guc *guc) return; } + if (i915.guc_log_level >= 0) { + /* Create a WC (Uncached for read) mapping so that we + * can directly get the data (up-to-date) from memory. + * Also create the mapping now only to properly handle + * the flush interrupts which can come before we create + * a relay channel at the end of Driver load. + */ + void *vaddr = i915_gem_object_pin_map(obj, true); + if (IS_ERR(vaddr)) { + DRM_DEBUG_DRIVER("Couldn't map log buffer %ld\n", + PTR_ERR(vaddr)); + gem_release_guc_obj(obj); + i915.guc_log_level = -1; + return; + } + + guc->log.buf_addr = vaddr; + } + guc->log.obj = obj; } diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 3e90279..5e6accb 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -127,6 +127,7 @@ struct intel_guc_log { struct drm_i915_gem_object *obj; struct workqueue_struct *wq; struct rchan *relay_chan; + void *buf_addr; }; struct intel_guc {