From patchwork Wed Sep 18 04:12:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 2904651 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 376579F1E3 for ; Wed, 18 Sep 2013 04:16:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3906320119 for ; Wed, 18 Sep 2013 04:16:42 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 2F8CB20117 for ; Wed, 18 Sep 2013 04:16:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2C9DBE61D2 for ; Tue, 17 Sep 2013 21:16:41 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail.bwidawsk.net (bwidawsk.net [166.78.191.112]) by gabe.freedesktop.org (Postfix) with ESMTP id 6CBEDE5EF3 for ; Tue, 17 Sep 2013 21:13:21 -0700 (PDT) Received: by mail.bwidawsk.net (Postfix, from userid 5001) id 0B97B59E22; Tue, 17 Sep 2013 21:13:21 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from lundgren.intel.com (c-24-21-100-90.hsd1.or.comcast.net [24.21.100.90]) by mail.bwidawsk.net (Postfix) with ESMTPSA id BA3D259E16; Tue, 17 Sep 2013 21:13:02 -0700 (PDT) From: Ben Widawsky To: Intel GFX Date: Tue, 17 Sep 2013 21:12:46 -0700 Message-Id: <1379477575-2164-5-git-send-email-benjamin.widawsky@intel.com> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1379477575-2164-1-git-send-email-benjamin.widawsky@intel.com> References: <1379477575-2164-1-git-send-email-benjamin.widawsky@intel.com> Cc: Bryan Bell , Ben Widawsky , Ben Widawsky Subject: [Intel-gfx] [PATCH 5/6] drm/i915: Do remaps for all contexts X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Virus-Scanned: ClamAV using ClamSMTP On both Ivybridge and Haswell, row remapping information is saved and restored with context. This means, we never actually properly supported the l3 remapping because our sysfs interface is asynchronous (and not tied to any context), and the known faulty HW would be reused by the next context to run. Not that due to the asynchronous nature of the sysfs entry, there is no point modifying the registers for the existing context. Instead we set a flag for all contexts to load the correct remapping information on the next run. Interested clients can use debugfs to determine whether or not the row has been remapped. One could propose at this point that we just do the remapping in the kernel. I guess since we have to maintain the sysfs interface anyway, I'm not sure how useful it is, and I do like keeping the policy in userspace; (it wasn't my original decision to make the interface the way it is, so I'm not attached). v2: Force a context switch when we have a remap on the next switch. (Ville) Don't let userspace use the interface with disabled contexts. Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_debugfs.c | 8 +++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem_context.c | 22 ++++++++++++++++---- drivers/gpu/drm/i915/i915_sysfs.c | 37 +++++++++++++-------------------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index ada0950..80bed69 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -145,6 +145,13 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) seq_printf(m, " (%s)", obj->ring->name); } +static void describe_ctx(struct seq_file *m, struct i915_hw_context *ctx) +{ + seq_putc(m, ctx->is_initialized ? 'I' : 'i'); + seq_putc(m, ctx->remap_slice ? 'R' : 'r'); + seq_putc(m, ' '); +} + static int i915_gem_object_list_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -1463,6 +1470,7 @@ static int i915_context_status(struct seq_file *m, void *unused) list_for_each_entry(ctx, &dev_priv->context_list, link) { seq_puts(m, "HW context "); + describe_ctx(m, ctx); for_each_ring(ring, dev_priv, i) if (ring->default_context == ctx) seq_printf(m, "(default context %s) ", ring->name); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1795927..015df52 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -601,6 +601,7 @@ struct i915_hw_context { struct kref ref; int id; bool is_initialized; + uint8_t remap_slice; struct drm_i915_file_private *file_priv; struct intel_ring_buffer *ring; struct drm_i915_gem_object *obj; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 2bbdce8..7e138cc 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -140,7 +140,7 @@ create_hw_context(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; - int ret; + int ret, i; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (ctx == NULL) @@ -181,6 +181,8 @@ create_hw_context(struct drm_device *dev, ctx->file_priv = file_priv; ctx->id = ret; + for (i = 0; i < NUM_L3_SLICES(dev); i++) + ctx->remap_slice |= 1 << 1; return ctx; @@ -396,11 +398,11 @@ static int do_switch(struct i915_hw_context *to) struct intel_ring_buffer *ring = to->ring; struct i915_hw_context *from = ring->last_context; u32 hw_flags = 0; - int ret; + int ret, i; BUG_ON(from != NULL && from->obj != NULL && from->obj->pin_count == 0); - if (from == to) + if (from == to && !to->remap_slice) return 0; ret = i915_gem_obj_ggtt_pin(to->obj, CONTEXT_ALIGN, false, false); @@ -423,7 +425,7 @@ static int do_switch(struct i915_hw_context *to) if (!to->is_initialized || is_default_context(to)) hw_flags |= MI_RESTORE_INHIBIT; - else if (WARN_ON_ONCE(from == to)) /* not yet expected */ + else if (from == to) hw_flags |= MI_FORCE_RESTORE; ret = mi_set_context(ring, to, hw_flags); @@ -432,6 +434,18 @@ static int do_switch(struct i915_hw_context *to) return ret; } + for (i = 0; i < MAX_L3_SLICES; i++) { + if (!(to->remap_slice & (1<remap_slice &= ~(1<dev; struct drm_i915_private *dev_priv = drm_dev->dev_private; - uint32_t misccpctl; int slice = (int)(uintptr_t)attr->private; - int i, ret; + int ret; count = round_down(count, 4); @@ -134,26 +133,13 @@ i915_l3_read(struct file *filp, struct kobject *kobj, if (ret) return ret; - if (IS_HASWELL(drm_dev)) { - if (dev_priv->l3_parity.remap_info[slice]) - memcpy(buf, - dev_priv->l3_parity.remap_info[slice] + (offset/4), - count); - else - memset(buf, 0, count); - - goto out; - } - - misccpctl = I915_READ(GEN7_MISCCPCTL); - I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE); - - for (i = 0; i < count; i += 4) - *((uint32_t *)(&buf[i])) = I915_READ(GEN7_L3LOG_BASE + offset + i); - - I915_WRITE(GEN7_MISCCPCTL, misccpctl); + if (dev_priv->l3_parity.remap_info[slice]) + memcpy(buf, + dev_priv->l3_parity.remap_info[slice] + (offset/4), + count); + else + memset(buf, 0, count); -out: mutex_unlock(&drm_dev->struct_mutex); return count; @@ -168,6 +154,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj, struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev); struct drm_device *drm_dev = dminor->dev; struct drm_i915_private *dev_priv = drm_dev->dev_private; + struct i915_hw_context *ctx; u32 *temp = NULL; /* Just here to make handling failures easy */ int slice = (int)(uintptr_t)attr->private; int ret; @@ -176,6 +163,9 @@ i915_l3_write(struct file *filp, struct kobject *kobj, if (ret) return ret; + if (dev_priv->hw_contexts_disabled) + return -ENXIO; + ret = i915_mutex_lock_interruptible(drm_dev); if (ret) return ret; @@ -204,8 +194,9 @@ i915_l3_write(struct file *filp, struct kobject *kobj, memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count); - if (i915_gem_l3_remap(&dev_priv->ring[RCS], slice)) - count = 0; + /* NB: We defer the remapping until we switch to the context */ + list_for_each_entry(ctx, &dev_priv->context_list, link) + ctx->remap_slice |= (1<struct_mutex);