From: Greg Kroah-Hartman Date: Mon, 2 Dec 2013 01:12:58 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.4.72~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bf208909446f6b23788ef9dfbb04fec2cf26fee;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches added patches: drm-i915-dvo-call-mode_set-callback-only-when-the-port-is-running.patch drm-i915-flush-cursors-harder.patch drm-i915-replicate-bios-edp-bpp-clamping-hack-for-hsw.patch drm-i915-restore-the-early-forcewake-cleanup.patch drm-nouveau-when-bailing-out-of-a-pushbuf-ioctl-do-not-remove-previous-fence.patch drm-ttm-fix-memory-type-compatibility-check.patch drm-ttm-fix-ttm_bo_move_memcpy.patch drm-ttm-handle-in-memory-region-copies.patch drm-vmwgfx-resource-evict-fixes.patch --- diff --git a/queue-3.12/drm-i915-dvo-call-mode_set-callback-only-when-the-port-is-running.patch b/queue-3.12/drm-i915-dvo-call-mode_set-callback-only-when-the-port-is-running.patch new file mode 100644 index 00000000000..bee3aca2b98 --- /dev/null +++ b/queue-3.12/drm-i915-dvo-call-mode_set-callback-only-when-the-port-is-running.patch @@ -0,0 +1,79 @@ +From 48f34e10169dbb3dd7a19af64e328492b7f54af4 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Tue, 8 Oct 2013 12:25:42 +0200 +Subject: drm/i915/dvo: call ->mode_set callback only when the port is running + +From: Daniel Vetter + +commit 48f34e10169dbb3dd7a19af64e328492b7f54af4 upstream. + +The ns2501 controller seems to need the dpll and dvo port to accept +the timing update commands. Quick testing on my x30 here seems to +indicate that other dvo controllers don't mind. So let's move the +->mode_set callback to a place where we have the port up and running +already. + +Tested-by: Chris Wilson +Tested-by: Thomas Richter +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_dvo.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_dvo.c ++++ b/drivers/gpu/drm/i915/intel_dvo.c +@@ -171,11 +171,16 @@ static void intel_enable_dvo(struct inte + { + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dvo *intel_dvo = enc_to_dvo(encoder); ++ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + u32 dvo_reg = intel_dvo->dev.dvo_reg; + u32 temp = I915_READ(dvo_reg); + + I915_WRITE(dvo_reg, temp | DVO_ENABLE); + I915_READ(dvo_reg); ++ intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, ++ &crtc->config.requested_mode, ++ &crtc->config.adjusted_mode); ++ + intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); + } + +@@ -184,6 +189,7 @@ static void intel_dvo_dpms(struct drm_co + { + struct intel_dvo *intel_dvo = intel_attached_dvo(connector); + struct drm_crtc *crtc; ++ struct intel_crtc_config *config; + + /* dvo supports only 2 dpms states. */ + if (mode != DRM_MODE_DPMS_ON) +@@ -204,10 +210,16 @@ static void intel_dvo_dpms(struct drm_co + /* We call connector dpms manually below in case pipe dpms doesn't + * change due to cloning. */ + if (mode == DRM_MODE_DPMS_ON) { ++ config = &to_intel_crtc(crtc)->config; ++ + intel_dvo->base.connectors_active = true; + + intel_crtc_update_dpms(crtc); + ++ intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, ++ &config->requested_mode, ++ &config->adjusted_mode); ++ + intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); + } else { + intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false); +@@ -299,10 +311,6 @@ static void intel_dvo_mode_set(struct in + break; + } + +- intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, +- &crtc->config.requested_mode, +- adjusted_mode); +- + /* Save the data order, since I don't know what it should be set to. */ + dvo_val = I915_READ(dvo_reg) & + (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); diff --git a/queue-3.12/drm-i915-flush-cursors-harder.patch b/queue-3.12/drm-i915-flush-cursors-harder.patch new file mode 100644 index 00000000000..452bee2745e --- /dev/null +++ b/queue-3.12/drm-i915-flush-cursors-harder.patch @@ -0,0 +1,50 @@ +From b2ea8ef559b4d94190009f3651b5b3ab7c05afd3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 4 Nov 2013 08:13:45 +0100 +Subject: drm/i915: flush cursors harder + +From: Daniel Vetter + +commit b2ea8ef559b4d94190009f3651b5b3ab7c05afd3 upstream. + +Apparently they need the same treatment as primary planes. This fixes +modesetting failures because of stuck cursors (!) on Thomas' i830M +machine. + +I've figured while at it I'll also roll it out for the ivb 3 pipe +version of this function. I didn't do this for i845/i865 since Bspec +says the update mechanism works differently, and there's some +additional rules about what can be updated in which order. + +Tested-by: Thomas Richter +Cc: Thomas Richter +Cc: Ville Syrjälä +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_display.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -6770,7 +6770,9 @@ static void i9xx_update_cursor(struct dr + intel_crtc->cursor_visible = visible; + } + /* and commit changes on next vblank */ ++ POSTING_READ(CURCNTR(pipe)); + I915_WRITE(CURBASE(pipe), base); ++ POSTING_READ(CURBASE(pipe)); + } + + static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) +@@ -6799,7 +6801,9 @@ static void ivb_update_cursor(struct drm + intel_crtc->cursor_visible = visible; + } + /* and commit changes on next vblank */ ++ POSTING_READ(CURCNTR_IVB(pipe)); + I915_WRITE(CURBASE_IVB(pipe), base); ++ POSTING_READ(CURBASE_IVB(pipe)); + } + + /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ diff --git a/queue-3.12/drm-i915-replicate-bios-edp-bpp-clamping-hack-for-hsw.patch b/queue-3.12/drm-i915-replicate-bios-edp-bpp-clamping-hack-for-hsw.patch new file mode 100644 index 00000000000..ffa9b0c4476 --- /dev/null +++ b/queue-3.12/drm-i915-replicate-bios-edp-bpp-clamping-hack-for-hsw.patch @@ -0,0 +1,61 @@ +From 1021442098ee9328fdd4d113d63a3a7f2f40c37b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 18 Nov 2013 07:38:16 +0100 +Subject: drm/i915: Replicate BIOS eDP bpp clamping hack for hsw + +From: Daniel Vetter + +commit 1021442098ee9328fdd4d113d63a3a7f2f40c37b upstream. + +Haswell's DDI encoders have their own ->get_config callback and in + +commit c6cd2ee2d59111a07cd9199564c9bdcb2d11e5cf +Author: Jani Nikula +Date: Mon Oct 21 10:52:07 2013 +0300 + + drm/i915/dp: workaround BIOS eDP bpp clamping issue + +we've forgotten to replicate this hack. So let's do it that. + +Note for backporters: The above commit and all it's depencies need to +be backported first. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71049 +Tested-by: Gökçen Eraslan +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_ddi.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_ddi.c ++++ b/drivers/gpu/drm/i915/intel_ddi.c +@@ -1285,6 +1285,26 @@ void intel_ddi_get_config(struct intel_e + default: + break; + } ++ ++ if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp && ++ pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { ++ /* ++ * This is a big fat ugly hack. ++ * ++ * Some machines in UEFI boot mode provide us a VBT that has 18 ++ * bpp and 1.62 GHz link bandwidth for eDP, which for reasons ++ * unknown we fail to light up. Yet the same BIOS boots up with ++ * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as ++ * max, not what it tells us to use. ++ * ++ * Note: This will still be broken if the eDP panel is not lit ++ * up by the BIOS, and thus we can't get the mode at module ++ * load. ++ */ ++ DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", ++ pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); ++ dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; ++ } + } + + static void intel_ddi_destroy(struct drm_encoder *encoder) diff --git a/queue-3.12/drm-i915-restore-the-early-forcewake-cleanup.patch b/queue-3.12/drm-i915-restore-the-early-forcewake-cleanup.patch new file mode 100644 index 00000000000..798eb3b745f --- /dev/null +++ b/queue-3.12/drm-i915-restore-the-early-forcewake-cleanup.patch @@ -0,0 +1,82 @@ +From ef46e0d247da0a7a408573aa15870e231bbd4af2 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 16 Nov 2013 16:00:09 +0100 +Subject: drm/i915: restore the early forcewake cleanup + +From: Daniel Vetter + +commit ef46e0d247da0a7a408573aa15870e231bbd4af2 upstream. + +Some BIOS just leak the forcewak bits, which we clean up. +Unfortunately this has been broken in + +commit 521198a2e7095c8c7daa8d7d3a76a110c346be6f +Author: Mika Kuoppala +Date: Fri Aug 23 16:52:30 2013 +0300 + + drm/i915: sanitize forcewake registers on reset + +To make this work both for resets and for BIOS takeover just add the +forcewake clearing call back to intel_uncore_early_sanitize. + +We need to clear the forcewake in early sanitize so that the forcewak +dance in intel_uncore_init (to figure out whether we have mt or legacy +forcewake on ivb) works. That cleanup fits in nicely with the general +topic of early_sanitize to prepare for the very first mmio ops. + +Cc: Mika Kuoppala +Cc: Chris Wilson +Reported-by: Jörg Otte +Cc: Jörg Otte +References: https://lkml.org/lkml/2013/11/16/40 +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_uncore.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_uncore.c ++++ b/drivers/gpu/drm/i915/intel_uncore.c +@@ -204,6 +204,19 @@ static void vlv_force_wake_put(struct dr + gen6_gt_check_fifodbg(dev_priv); + } + ++static void intel_uncore_forcewake_reset(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ if (IS_VALLEYVIEW(dev)) { ++ vlv_force_wake_reset(dev_priv); ++ } else if (INTEL_INFO(dev)->gen >= 6) { ++ __gen6_gt_force_wake_reset(dev_priv); ++ if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) ++ __gen6_gt_force_wake_mt_reset(dev_priv); ++ } ++} ++ + void intel_uncore_early_sanitize(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -259,19 +272,8 @@ void intel_uncore_init(struct drm_device + dev_priv->uncore.funcs.force_wake_put = + __gen6_gt_force_wake_put; + } +-} +- +-static void intel_uncore_forcewake_reset(struct drm_device *dev) +-{ +- struct drm_i915_private *dev_priv = dev->dev_private; + +- if (IS_VALLEYVIEW(dev)) { +- vlv_force_wake_reset(dev_priv); +- } else if (INTEL_INFO(dev)->gen >= 6) { +- __gen6_gt_force_wake_reset(dev_priv); +- if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) +- __gen6_gt_force_wake_mt_reset(dev_priv); +- } ++ intel_uncore_forcewake_reset(dev); + } + + void intel_uncore_sanitize(struct drm_device *dev) diff --git a/queue-3.12/drm-nouveau-when-bailing-out-of-a-pushbuf-ioctl-do-not-remove-previous-fence.patch b/queue-3.12/drm-nouveau-when-bailing-out-of-a-pushbuf-ioctl-do-not-remove-previous-fence.patch new file mode 100644 index 00000000000..3ac178f4aec --- /dev/null +++ b/queue-3.12/drm-nouveau-when-bailing-out-of-a-pushbuf-ioctl-do-not-remove-previous-fence.patch @@ -0,0 +1,28 @@ +From 9360bd1112d8874d21942e2ae74f5416b00a8db6 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Wed, 13 Nov 2013 15:18:32 +1000 +Subject: drm/nouveau: when bailing out of a pushbuf ioctl, do not remove previous fence + +From: Ben Skeggs + +commit 9360bd1112d8874d21942e2ae74f5416b00a8db6 upstream. + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nouveau_gem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -317,7 +317,8 @@ validate_fini_list(struct list_head *lis + list_for_each_safe(entry, tmp, list) { + nvbo = list_entry(entry, struct nouveau_bo, entry); + +- nouveau_bo_fence(nvbo, fence); ++ if (likely(fence)) ++ nouveau_bo_fence(nvbo, fence); + + if (unlikely(nvbo->validate_mapped)) { + ttm_bo_kunmap(&nvbo->kmap); diff --git a/queue-3.12/drm-ttm-fix-memory-type-compatibility-check.patch b/queue-3.12/drm-ttm-fix-memory-type-compatibility-check.patch new file mode 100644 index 00000000000..875b4a0d71f --- /dev/null +++ b/queue-3.12/drm-ttm-fix-memory-type-compatibility-check.patch @@ -0,0 +1,92 @@ +From 59c8e66378fb78adbcd05f0d09783dde6fef282b Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Mon, 28 Oct 2013 02:02:19 -0700 +Subject: drm/ttm: Fix memory type compatibility check + +From: Thomas Hellstrom + +commit 59c8e66378fb78adbcd05f0d09783dde6fef282b upstream. + +Also check the busy placements before deciding to move a buffer object. +Failing to do this may result in a completely unneccessary move within a +single memory type. + +Signed-off-by: Thomas Hellstrom +Reviewed-by: Jakob Bornecrantz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/ttm/ttm_bo.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -986,24 +986,32 @@ out_unlock: + return ret; + } + +-static int ttm_bo_mem_compat(struct ttm_placement *placement, +- struct ttm_mem_reg *mem) ++static bool ttm_bo_mem_compat(struct ttm_placement *placement, ++ struct ttm_mem_reg *mem, ++ uint32_t *new_flags) + { + int i; + + if (mem->mm_node && placement->lpfn != 0 && + (mem->start < placement->fpfn || + mem->start + mem->num_pages > placement->lpfn)) +- return -1; ++ return false; + + for (i = 0; i < placement->num_placement; i++) { +- if ((placement->placement[i] & mem->placement & +- TTM_PL_MASK_CACHING) && +- (placement->placement[i] & mem->placement & +- TTM_PL_MASK_MEM)) +- return i; ++ *new_flags = placement->placement[i]; ++ if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) && ++ (*new_flags & mem->placement & TTM_PL_MASK_MEM)) ++ return true; + } +- return -1; ++ ++ for (i = 0; i < placement->num_busy_placement; i++) { ++ *new_flags = placement->busy_placement[i]; ++ if ((*new_flags & mem->placement & TTM_PL_MASK_CACHING) && ++ (*new_flags & mem->placement & TTM_PL_MASK_MEM)) ++ return true; ++ } ++ ++ return false; + } + + int ttm_bo_validate(struct ttm_buffer_object *bo, +@@ -1012,6 +1020,7 @@ int ttm_bo_validate(struct ttm_buffer_ob + bool no_wait_gpu) + { + int ret; ++ uint32_t new_flags; + + lockdep_assert_held(&bo->resv->lock.base); + /* Check that range is valid */ +@@ -1022,8 +1031,7 @@ int ttm_bo_validate(struct ttm_buffer_ob + /* + * Check whether we need to move buffer. + */ +- ret = ttm_bo_mem_compat(placement, &bo->mem); +- if (ret < 0) { ++ if (!ttm_bo_mem_compat(placement, &bo->mem, &new_flags)) { + ret = ttm_bo_move_buffer(bo, placement, interruptible, + no_wait_gpu); + if (ret) +@@ -1033,7 +1041,7 @@ int ttm_bo_validate(struct ttm_buffer_ob + * Use the access and other non-mapping-related flag bits from + * the compatible memory placement flags to the active flags + */ +- ttm_flag_masked(&bo->mem.placement, placement->placement[ret], ++ ttm_flag_masked(&bo->mem.placement, new_flags, + ~TTM_PL_MASK_MEMTYPE); + } + /* diff --git a/queue-3.12/drm-ttm-fix-ttm_bo_move_memcpy.patch b/queue-3.12/drm-ttm-fix-ttm_bo_move_memcpy.patch new file mode 100644 index 00000000000..82cc3da517f --- /dev/null +++ b/queue-3.12/drm-ttm-fix-ttm_bo_move_memcpy.patch @@ -0,0 +1,82 @@ +From da95c788ef0c645378ffccb7060a0df1a33aee38 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Wed, 30 Oct 2013 03:29:50 -0700 +Subject: drm/ttm: Fix ttm_bo_move_memcpy + +From: Thomas Hellstrom + +commit da95c788ef0c645378ffccb7060a0df1a33aee38 upstream. + +All error paths will want to keep the mm node, so handle this at the +function exit. This fixes an ioremap failure error path. +Also add some comments to make the function a bit easier to understand. + +Signed-off-by: Thomas Hellstrom +Reviewed-by: Jakob Bornecrantz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/ttm/ttm_bo_util.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/ttm/ttm_bo_util.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_util.c +@@ -343,21 +343,25 @@ int ttm_bo_move_memcpy(struct ttm_buffer + if (ret) + goto out; + ++ /* ++ * Single TTM move. NOP. ++ */ + if (old_iomap == NULL && new_iomap == NULL) + goto out2; ++ ++ /* ++ * Move nonexistent data. NOP. ++ */ + if (old_iomap == NULL && ttm == NULL) + goto out2; + +- /* TTM might be null for moves within the same region. ++ /* ++ * TTM might be null for moves within the same region. + */ + if (ttm && ttm->state == tt_unpopulated) { + ret = ttm->bdev->driver->ttm_tt_populate(ttm); +- if (ret) { +- /* if we fail here don't nuke the mm node +- * as the bo still owns it */ +- old_copy.mm_node = NULL; ++ if (ret) + goto out1; +- } + } + + add = 0; +@@ -383,11 +387,8 @@ int ttm_bo_move_memcpy(struct ttm_buffer + prot); + } else + ret = ttm_copy_io_page(new_iomap, old_iomap, page); +- if (ret) { +- /* failing here, means keep old copy as-is */ +- old_copy.mm_node = NULL; ++ if (ret) + goto out1; +- } + } + mb(); + out2: +@@ -405,7 +406,12 @@ out1: + ttm_mem_reg_iounmap(bdev, old_mem, new_iomap); + out: + ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap); +- ttm_bo_mem_put(bo, &old_copy); ++ ++ /* ++ * On error, keep the mm node! ++ */ ++ if (!ret) ++ ttm_bo_mem_put(bo, &old_copy); + return ret; + } + EXPORT_SYMBOL(ttm_bo_move_memcpy); diff --git a/queue-3.12/drm-ttm-handle-in-memory-region-copies.patch b/queue-3.12/drm-ttm-handle-in-memory-region-copies.patch new file mode 100644 index 00000000000..253dfb30784 --- /dev/null +++ b/queue-3.12/drm-ttm-handle-in-memory-region-copies.patch @@ -0,0 +1,33 @@ +From 9a0599ddeae012a771bba5e23393fc52d8a59d89 Mon Sep 17 00:00:00 2001 +From: Jakob Bornecrantz +Date: Wed, 30 Oct 2013 02:46:56 -0700 +Subject: drm/ttm: Handle in-memory region copies + +From: Jakob Bornecrantz + +commit 9a0599ddeae012a771bba5e23393fc52d8a59d89 upstream. + +Fix the case where the ttm pointer may be NULL causing +a NULL pointer dereference. + +Signed-off-by: Jakob Bornecrantz +Signed-off-by: Thomas Hellström +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/ttm/ttm_bo_util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/ttm/ttm_bo_util.c ++++ b/drivers/gpu/drm/ttm/ttm_bo_util.c +@@ -348,7 +348,9 @@ int ttm_bo_move_memcpy(struct ttm_buffer + if (old_iomap == NULL && ttm == NULL) + goto out2; + +- if (ttm->state == tt_unpopulated) { ++ /* TTM might be null for moves within the same region. ++ */ ++ if (ttm && ttm->state == tt_unpopulated) { + ret = ttm->bdev->driver->ttm_tt_populate(ttm); + if (ret) { + /* if we fail here don't nuke the mm node diff --git a/queue-3.12/drm-vmwgfx-resource-evict-fixes.patch b/queue-3.12/drm-vmwgfx-resource-evict-fixes.patch new file mode 100644 index 00000000000..7b687e572cf --- /dev/null +++ b/queue-3.12/drm-vmwgfx-resource-evict-fixes.patch @@ -0,0 +1,131 @@ +From ea029c28deadc33d2af4baf26810dd5fc44d4926 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Tue, 12 Nov 2013 00:09:54 -0800 +Subject: drm/vmwgfx: Resource evict fixes + +From: Thomas Hellstrom + +commit ea029c28deadc33d2af4baf26810dd5fc44d4926 upstream. + +Fix an error message that was incorrectly blaming device resource id +shortage. + +Also make sure we correctly catch resource eviction errors, that +could otherwise lead to evictable resources temporarily not being on the +LRU list. + +Signed-off-by: Thomas Hellstrom +Reviewed-by: Jakob Bornecrantz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 42 ++++++++++++++++++++++++++----- + 1 file changed, 36 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +@@ -32,6 +32,8 @@ + #include + #include "vmwgfx_resource_priv.h" + ++#define VMW_RES_EVICT_ERR_COUNT 10 ++ + struct vmw_user_dma_buffer { + struct ttm_base_object base; + struct vmw_dma_buffer dma; +@@ -1091,8 +1093,9 @@ vmw_resource_backoff_reservation(struct + * to a backup buffer. + * + * @res: The resource to evict. ++ * @interruptible: Whether to wait interruptible. + */ +-int vmw_resource_do_evict(struct vmw_resource *res) ++int vmw_resource_do_evict(struct vmw_resource *res, bool interruptible) + { + struct ttm_validate_buffer val_buf; + const struct vmw_res_func *func = res->func; +@@ -1102,7 +1105,8 @@ int vmw_resource_do_evict(struct vmw_res + BUG_ON(!func->may_evict); + + val_buf.bo = NULL; +- ret = vmw_resource_check_buffer(res, &ticket, true, &val_buf); ++ ret = vmw_resource_check_buffer(res, &ticket, interruptible, ++ &val_buf); + if (unlikely(ret != 0)) + return ret; + +@@ -1141,6 +1145,7 @@ int vmw_resource_validate(struct vmw_res + struct vmw_private *dev_priv = res->dev_priv; + struct list_head *lru_list = &dev_priv->res_lru[res->func->res_type]; + struct ttm_validate_buffer val_buf; ++ unsigned err_count = 0; + + if (likely(!res->func->may_evict)) + return 0; +@@ -1155,7 +1160,7 @@ int vmw_resource_validate(struct vmw_res + + write_lock(&dev_priv->resource_lock); + if (list_empty(lru_list) || !res->func->may_evict) { +- DRM_ERROR("Out of device device id entries " ++ DRM_ERROR("Out of device device resources " + "for %s.\n", res->func->type_name); + ret = -EBUSY; + write_unlock(&dev_priv->resource_lock); +@@ -1168,7 +1173,19 @@ int vmw_resource_validate(struct vmw_res + list_del_init(&evict_res->lru_head); + + write_unlock(&dev_priv->resource_lock); +- vmw_resource_do_evict(evict_res); ++ ++ ret = vmw_resource_do_evict(evict_res, true); ++ if (unlikely(ret != 0)) { ++ write_lock(&dev_priv->resource_lock); ++ list_add_tail(&evict_res->lru_head, lru_list); ++ write_unlock(&dev_priv->resource_lock); ++ if (ret == -ERESTARTSYS || ++ ++err_count > VMW_RES_EVICT_ERR_COUNT) { ++ vmw_resource_unreference(&evict_res); ++ goto out_no_validate; ++ } ++ } ++ + vmw_resource_unreference(&evict_res); + } while (1); + +@@ -1253,13 +1270,15 @@ bool vmw_resource_needs_backup(const str + * @type: The resource type to evict + * + * To avoid thrashing starvation or as part of the hibernation sequence, +- * evict all evictable resources of a specific type. ++ * try to evict all evictable resources of a specific type. + */ + static void vmw_resource_evict_type(struct vmw_private *dev_priv, + enum vmw_res_type type) + { + struct list_head *lru_list = &dev_priv->res_lru[type]; + struct vmw_resource *evict_res; ++ unsigned err_count = 0; ++ int ret; + + do { + write_lock(&dev_priv->resource_lock); +@@ -1272,7 +1291,18 @@ static void vmw_resource_evict_type(stru + lru_head)); + list_del_init(&evict_res->lru_head); + write_unlock(&dev_priv->resource_lock); +- vmw_resource_do_evict(evict_res); ++ ++ ret = vmw_resource_do_evict(evict_res, false); ++ if (unlikely(ret != 0)) { ++ write_lock(&dev_priv->resource_lock); ++ list_add_tail(&evict_res->lru_head, lru_list); ++ write_unlock(&dev_priv->resource_lock); ++ if (++err_count > VMW_RES_EVICT_ERR_COUNT) { ++ vmw_resource_unreference(&evict_res); ++ return; ++ } ++ } ++ + vmw_resource_unreference(&evict_res); + } while (1); + diff --git a/queue-3.12/series b/queue-3.12/series index ca6728b2926..3c712913dad 100644 --- a/queue-3.12/series +++ b/queue-3.12/series @@ -121,3 +121,12 @@ prism54-set-netdev-type-to-wlan.patch regulator-pfuze100-allow-misprogrammed-id.patch sony-laptop-do-not-scribble-keyboard-backlight-registers-on.patch ftrace-fix-function-graph-with-loading-of-modules.patch +drm-vmwgfx-resource-evict-fixes.patch +drm-ttm-fix-memory-type-compatibility-check.patch +drm-ttm-handle-in-memory-region-copies.patch +drm-ttm-fix-ttm_bo_move_memcpy.patch +drm-i915-dvo-call-mode_set-callback-only-when-the-port-is-running.patch +drm-i915-flush-cursors-harder.patch +drm-i915-restore-the-early-forcewake-cleanup.patch +drm-i915-replicate-bios-edp-bpp-clamping-hack-for-hsw.patch +drm-nouveau-when-bailing-out-of-a-pushbuf-ioctl-do-not-remove-previous-fence.patch