From patchwork Tue Dec 7 14:33:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 12661989 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6D946C433EF for ; Tue, 7 Dec 2021 14:34:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A0C3F73B88; Tue, 7 Dec 2021 14:34:01 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 85ECA6E199 for ; Tue, 7 Dec 2021 14:33:58 +0000 (UTC) X-IronPort-AV: E=McAfee;i="6200,9189,10190"; a="298380801" X-IronPort-AV: E=Sophos;i="5.87,293,1631602800"; d="scan'208";a="298380801" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Dec 2021 06:33:58 -0800 X-IronPort-AV: E=Sophos;i="5.87,293,1631602800"; d="scan'208";a="515296100" Received: from ramaling-i9x.iind.intel.com ([10.99.66.205]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Dec 2021 06:33:55 -0800 From: Ramalingam C To: intel-gfx Date: Tue, 7 Dec 2021 20:03:35 +0530 Message-Id: <20211207143336.11381-2-ramalingam.c@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20211207143336.11381-1-ramalingam.c@intel.com> References: <20211207143336.11381-1-ramalingam.c@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 1/2] drm/i915: Sanitycheck device iomem on probe X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: CQ Tang , Andi , Matthew Auld , Chris Wilson Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Chris Wilson As we setup the memory regions for the device, give each a quick test to verify that we can read and write to the full iomem range. This ensures that our physical addressing for the device's memory is correct, and some reassurance that the memory is functional. Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: CQ Tang Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/intel_memory_region.c | 104 +++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index b43121609e25..c53e07f1d0c0 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -3,6 +3,8 @@ * Copyright © 2019 Intel Corporation */ +#include + #include "intel_memory_region.h" #include "i915_drv.h" #include "i915_ttm_buddy_manager.h" @@ -29,6 +31,99 @@ static const struct { }, }; +static int __iopagetest(struct intel_memory_region *mem, + u8 __iomem *va, int pagesize, + u8 value, resource_size_t offset, + const void *caller) +{ + int byte = prandom_u32_max(pagesize); + u8 result[3]; + + memset_io(va, value, pagesize); /* or GPF! */ + wmb(); + + result[0] = ioread8(va); + result[1] = ioread8(va + byte); + result[2] = ioread8(va + pagesize - 1); + if (memchr_inv(result, value, sizeof(result))) { + dev_err(mem->i915->drm.dev, + "Failed to read back from memory region:%pR at [%pa + %pa] for %ps; wrote %x, read (%x, %x, %x)\n", + &mem->region, &mem->io_start, &offset, caller, + value, result[0], result[1], result[2]); + return -EINVAL; + } + + return 0; +} + +static int iopagetest(struct intel_memory_region *mem, + resource_size_t offset, + const void *caller) +{ + const u8 val[] = { 0x0, 0xa5, 0xc3, 0xf0 }; + void __iomem *va; + int err; + int i; + + va = ioremap_wc(mem->io_start + offset, PAGE_SIZE); + if (!va) { + dev_err(mem->i915->drm.dev, + "Failed to ioremap memory region [%pa + %px] for %ps\n", + &mem->io_start, &offset, caller); + return -EFAULT; + } + + for (i = 0; i < ARRAY_SIZE(val); i++) { + err = __iopagetest(mem, va, PAGE_SIZE, val[i], offset, caller); + if (err) + break; + + err = __iopagetest(mem, va, PAGE_SIZE, ~val[i], offset, caller); + if (err) + break; + } + + iounmap(va); + return err; +} + +static resource_size_t random_page(resource_size_t last) +{ + /* Limited to low 44b (16TiB), but should suffice for a spot check */ + return prandom_u32_max(last >> PAGE_SHIFT) << PAGE_SHIFT; +} + +static int iomemtest(struct intel_memory_region *mem, const void *caller) +{ + resource_size_t last = resource_size(&mem->region) - PAGE_SIZE; + int err; + + /* + * Quick test to check read/write access to the iomap (backing store). + * + * Write a byte, read it back. If the iomapping fails, we expect + * a GPF preventing further execution. If the backing store does not + * exist, the read back will return garbage. We check a couple of pages, + * the first and last of the specified region to confirm the backing + * store + iomap does cover the entire memory region; and we check + * a random offset within as a quick spot check for bad memory. + */ + + err = iopagetest(mem, 0, caller); + if (err) + return err; + + err = iopagetest(mem, last, caller); + if (err) + return err; + + err = iopagetest(mem, random_page(last), caller); + if (err) + return err; + + return 0; +} + struct intel_memory_region * intel_memory_region_lookup(struct drm_i915_private *i915, u16 class, u16 instance) @@ -126,8 +221,17 @@ intel_memory_region_create(struct drm_i915_private *i915, goto err_free; } + if (io_start && IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) { + err = iomemtest(mem, (void *)_RET_IP_); + if (err) + goto err_release; + } + return mem; +err_release: + if (mem->ops->release) + mem->ops->release(mem); err_free: kfree(mem); return ERR_PTR(err); From patchwork Tue Dec 7 14:33:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ramalingam C X-Patchwork-Id: 12661991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B69C3C4332F for ; Tue, 7 Dec 2021 14:34:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2B495738B2; Tue, 7 Dec 2021 14:34:03 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8E84B738B2 for ; Tue, 7 Dec 2021 14:34:01 +0000 (UTC) X-IronPort-AV: E=McAfee;i="6200,9189,10190"; a="298380817" X-IronPort-AV: E=Sophos;i="5.87,293,1631602800"; d="scan'208";a="298380817" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Dec 2021 06:34:01 -0800 X-IronPort-AV: E=Sophos;i="5.87,293,1631602800"; d="scan'208";a="515296116" Received: from ramaling-i9x.iind.intel.com ([10.99.66.205]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Dec 2021 06:33:58 -0800 From: Ramalingam C To: intel-gfx Date: Tue, 7 Dec 2021 20:03:36 +0530 Message-Id: <20211207143336.11381-3-ramalingam.c@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20211207143336.11381-1-ramalingam.c@intel.com> References: <20211207143336.11381-1-ramalingam.c@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH 2/2] drm/i915: Test all device memory on probing X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: CQ Tang , Andi , Matthew Auld , Chris Wilson Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Chris Wilson This extends the previous sanitychecking of device memory to read/write all the memory on the device during the device probe, ala memtest86, as an optional module parameter: i915.memtest=1. This is not expected to be fast, but a reasonably thorough verfification that the device memory is accessible and doesn't return bit errors. Suggested-by: Matthew Auld Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: CQ Tang Signed-off-by: Ramalingam C --- drivers/gpu/drm/i915/i915_params.c | 3 ++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_memory_region.c | 36 ++++++++++++++-------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index e07f4cfea63a..525ae832aa9a 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -140,6 +140,9 @@ i915_param_named_unsafe(invert_brightness, int, 0400, i915_param_named(disable_display, bool, 0400, "Disable display (default: false)"); +i915_param_named(memtest, bool, 0400, + "Perform a read/write test of all device memory on module load (default: off)"); + i915_param_named(mmio_debug, int, 0400, "Enable the MMIO debug code for the first N failures (default: off). " "This may negatively affect performance."); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 8d725b64592d..c9d53ff910a0 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -64,6 +64,7 @@ struct drm_printer; param(char *, guc_firmware_path, NULL, 0400) \ param(char *, huc_firmware_path, NULL, 0400) \ param(char *, dmc_firmware_path, NULL, 0400) \ + param(bool, memtest, false, 0400) \ param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \ param(int, edp_vswing, 0, 0400) \ param(unsigned int, reset, 3, 0600) \ diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index c53e07f1d0c0..95adc2cf5dde 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -93,9 +93,12 @@ static resource_size_t random_page(resource_size_t last) return prandom_u32_max(last >> PAGE_SHIFT) << PAGE_SHIFT; } -static int iomemtest(struct intel_memory_region *mem, const void *caller) +static int iomemtest(struct intel_memory_region *mem, + bool test_all, + const void *caller) { resource_size_t last = resource_size(&mem->region) - PAGE_SIZE; + resource_size_t page; int err; /* @@ -109,17 +112,25 @@ static int iomemtest(struct intel_memory_region *mem, const void *caller) * a random offset within as a quick spot check for bad memory. */ - err = iopagetest(mem, 0, caller); - if (err) - return err; + if (test_all) { + for (page = 0; page <= last; page += PAGE_SIZE) { + err = iopagetest(mem, page, caller); + if (err) + return err; + } + } else { + err = iopagetest(mem, 0, caller); + if (err) + return err; - err = iopagetest(mem, last, caller); - if (err) - return err; + err = iopagetest(mem, last, caller); + if (err) + return err; - err = iopagetest(mem, random_page(last), caller); - if (err) - return err; + err = iopagetest(mem, random_page(last), caller); + if (err) + return err; + } return 0; } @@ -221,8 +232,9 @@ intel_memory_region_create(struct drm_i915_private *i915, goto err_free; } - if (io_start && IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) { - err = iomemtest(mem, (void *)_RET_IP_); + if (io_start && + (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) || i915->params.memtest)) { + err = iomemtest(mem, i915->params.memtest, (void *)_RET_IP_); if (err) goto err_release; }