From patchwork Mon May 25 17:48:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 6476671 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C47F2C0020 for ; Mon, 25 May 2015 17:49:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B39F0203B8 for ; Mon, 25 May 2015 17:49:16 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id A09D3203B7 for ; Mon, 25 May 2015 17:49:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ED49C6E109; Mon, 25 May 2015 10:49:13 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from relay.fireflyinternet.com (hostedrelay.fireflyinternet.com [109.228.30.76]) by gabe.freedesktop.org (Postfix) with ESMTP id B18C96E109 for ; Mon, 25 May 2015 10:49:12 -0700 (PDT) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by relay.fireflyinternet.com (FireflyRelay1) with ESMTP id 672602-1305619 for multiple; Mon, 25 May 2015 18:48:52 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Mon, 25 May 2015 18:48:44 +0100 Message-Id: <1432576124-20523-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1432568322-20651-1-git-send-email-chris@chris-wilson.co.uk> References: <1432568322-20651-1-git-send-email-chris@chris-wilson.co.uk> X-Authenticated-User: chris.alporthouse@surfanytime.net Cc: Akash Goel , stable@vger.kernel.org Subject: [Intel-gfx] [PATCH v2] drm/i915: Force wmb() on using GTT io_mapping_map_wc 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-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since the advent of mmap(wc), where we reused the same cache domain for WC and GTT paths (oh, how I regret that double-edged advice), we need to be extra cautious when using GTT iomap_wc internally. Since userspace maybe modifying through the mmap(wc) and we then modify modifying through an aliased WC path through the GTT, those writes may overlap and not be visible to the other path. Easiest to trigger appears to be write the batch through mmap(wc) and then attempt to perform reloc the GTT, corruption quickly ensues. v2: Be stricter and do a full mb() in case we are reading through one path and about to write through the second path. Also, apply the barriers on transitioning into the GTT domain as well to cover the white lie asychronous cases. Signed-off-by: Chris Wilson Cc: Akash Goel Cc: stable@vger.kernel.org --- drivers/gpu/drm/i915/i915_gem.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 517c5b8100d1..f17168b2cd37 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3923,7 +3923,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) int ret; if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) - return 0; + goto out; ret = i915_gem_object_wait_rendering(obj, !write); if (ret) @@ -3943,13 +3943,6 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) i915_gem_object_flush_cpu_write_domain(obj); - /* Serialise direct access to this object with the barriers for - * coherent writes from the GPU, by effectively invalidating the - * GTT domain upon first access. - */ - if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0) - mb(); - old_write_domain = obj->base.write_domain; old_read_domains = obj->base.read_domains; @@ -3977,6 +3970,23 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) list_move_tail(&vma->mm_list, &to_i915(obj->base.dev)->gtt.base.inactive_list); +out: + /* + * Userspace may be writing through mmap(wc) with + * write_domain=GTT (or even with a white lie unsynchronized write), + * so we need to explicitly flush before transitioning to writing + * through the GTT, or vice versa. As we reused the GTT cache domain + * for both paths, we must always have a memory barrier just in case. + * + * We need a full memory barrier in case we are reading through + * the GTT and before we starting through the WC (or vice versa). + * If we are only about to read through this access, we need only + * wait for any pending writes on the other path. + */ + if (write) + mb(); + else + wmb(); return 0; }