]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 22:02:17 +0000 (15:02 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 22:02:17 +0000 (15:02 -0700)
added patches:
drm-ast-fix-the-ast-open-key-function.patch
drm-fix-drm_ioctl_mode_getfb-handle-leak.patch
drm-i915-do-not-update-cursor-in-crtc-mode-set.patch
drm-i915-don-t-enable-the-cursor-on-a-disable-pipe.patch
drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch
drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip-code-deadlock.patch
drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch
drm-i915-try-not-to-lose-backlight-cblv-precision.patch
drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch
radeon-kms-fix-uninitialised-hotplug-work-usage-in-r100_irq_process.patch

queue-3.11/drm-ast-fix-the-ast-open-key-function.patch [new file with mode: 0644]
queue-3.11/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch [new file with mode: 0644]
queue-3.11/drm-i915-do-not-update-cursor-in-crtc-mode-set.patch [new file with mode: 0644]
queue-3.11/drm-i915-don-t-enable-the-cursor-on-a-disable-pipe.patch [new file with mode: 0644]
queue-3.11/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch [new file with mode: 0644]
queue-3.11/drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip-code-deadlock.patch [new file with mode: 0644]
queue-3.11/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch [new file with mode: 0644]
queue-3.11/drm-i915-try-not-to-lose-backlight-cblv-precision.patch [new file with mode: 0644]
queue-3.11/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch [new file with mode: 0644]
queue-3.11/radeon-kms-fix-uninitialised-hotplug-work-usage-in-r100_irq_process.patch [new file with mode: 0644]
queue-3.11/series

diff --git a/queue-3.11/drm-ast-fix-the-ast-open-key-function.patch b/queue-3.11/drm-ast-fix-the-ast-open-key-function.patch
new file mode 100644 (file)
index 0000000..c6eed88
--- /dev/null
@@ -0,0 +1,31 @@
+From 2e8378136f28bea960cec643d3fa5d843c9049ec Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Thu, 12 Sep 2013 15:31:04 +1000
+Subject: drm/ast: fix the ast open key function
+
+From: Dave Airlie <airlied@redhat.com>
+
+commit 2e8378136f28bea960cec643d3fa5d843c9049ec upstream.
+
+When porting from UMS I mistyped this from the wrong place, AST noticed
+and pointed it out, so we should fix it to be like the X.org driver.
+
+Reported-by: Y.C. Chen <yc_chen@aspeedtech.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ast/ast_drv.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/ast/ast_drv.h
++++ b/drivers/gpu/drm/ast/ast_drv.h
+@@ -177,7 +177,7 @@ uint8_t ast_get_index_reg_mask(struct as
+ static inline void ast_open_key(struct ast_private *ast)
+ {
+-      ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xA1, 0xFF, 0x04);
++      ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8);
+ }
+ #define AST_VIDMEM_SIZE_8M    0x00800000
diff --git a/queue-3.11/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch b/queue-3.11/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch
new file mode 100644 (file)
index 0000000..c31a42c
--- /dev/null
@@ -0,0 +1,75 @@
+From 101b96f32956ee99bf1468afaf572b88cda9f88b Mon Sep 17 00:00:00 2001
+From: David Herrmann <dh.herrmann@gmail.com>
+Date: Mon, 26 Aug 2013 15:16:49 +0200
+Subject: drm: fix DRM_IOCTL_MODE_GETFB handle-leak
+
+From: David Herrmann <dh.herrmann@gmail.com>
+
+commit 101b96f32956ee99bf1468afaf572b88cda9f88b upstream.
+
+DRM_IOCTL_MODE_GETFB is used to retrieve information about a given
+framebuffer ID. It is a read-only helper and was thus declassified for
+unprivileged access in:
+
+  commit a14b1b42477c5ef089fcda88cbaae50d979eb8f9
+  Author: Mandeep Singh Baines <mandeep.baines@gmail.com>
+  Date:   Fri Jan 20 12:11:16 2012 -0800
+
+      drm: remove master fd restriction on mode setting getters
+
+However, alongside width, height and stride information,
+DRM_IOCTL_MODE_GETFB also passes back a handle to the underlying buffer of
+the framebuffer. This handle allows users to mmap() it and read or write
+into it. Obviously, this should be restricted to DRM-Master.
+
+With the current setup, *any* process with access to /dev/dri/card0 (which
+means any process with access to hardware-accelerated rendering) can
+access the current screen framebuffer and modify it ad libitum.
+
+For backwards-compatibility reasons we want to keep the
+DRM_IOCTL_MODE_GETFB call unprivileged. Besides, it provides quite useful
+information regarding screen setup. So we simply test whether the caller
+is the current DRM-Master and if not, we return 0 as handle, which is
+always invalid. A following DRM_IOCTL_GEM_CLOSE on this handle will fail
+with EINVAL, but we accept this. Users shouldn't test for errors during
+GEM_CLOSE, anyway. And it is still better as a failing MODE_GETFB call.
+
+v2: add capable(CAP_SYS_ADMIN) check for compatibility with i-g-t
+
+Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_crtc.c |   18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -2604,10 +2604,22 @@ int drm_mode_getfb(struct drm_device *de
+       r->depth = fb->depth;
+       r->bpp = fb->bits_per_pixel;
+       r->pitch = fb->pitches[0];
+-      if (fb->funcs->create_handle)
+-              ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
+-      else
++      if (fb->funcs->create_handle) {
++              if (file_priv->is_master || capable(CAP_SYS_ADMIN)) {
++                      ret = fb->funcs->create_handle(fb, file_priv,
++                                                     &r->handle);
++              } else {
++                      /* GET_FB() is an unprivileged ioctl so we must not
++                       * return a buffer-handle to non-master processes! For
++                       * backwards-compatibility reasons, we cannot make
++                       * GET_FB() privileged, so just return an invalid handle
++                       * for non-masters. */
++                      r->handle = 0;
++                      ret = 0;
++              }
++      } else {
+               ret = -ENODEV;
++      }
+       drm_framebuffer_unreference(fb);
diff --git a/queue-3.11/drm-i915-do-not-update-cursor-in-crtc-mode-set.patch b/queue-3.11/drm-i915-do-not-update-cursor-in-crtc-mode-set.patch
new file mode 100644 (file)
index 0000000..b52d90c
--- /dev/null
@@ -0,0 +1,61 @@
+From cc173961a68034c1171a421f0dbed39edfb60880 Mon Sep 17 00:00:00 2001
+From: Jani Nikula <jani.nikula@intel.com>
+Date: Tue, 17 Sep 2013 18:33:43 +0300
+Subject: drm/i915: do not update cursor in crtc mode set
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+commit cc173961a68034c1171a421f0dbed39edfb60880 upstream.
+
+The cursor is disabled before crtc mode set in crtc disable (and we
+assert this is the case), and enabled afterwards in crtc enable. Do not
+update it in crtc mode set.
+
+On HSW enabling a plane on a disabled pipe may hang the entire system.
+And there's no good reason for doing it ever, so just don't.
+
+v2: Add note about HSW hangs - vsyrjala
+
+Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Tested-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c |    9 ---------
+ 1 file changed, 9 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4837,9 +4837,6 @@ static int i9xx_crtc_mode_set(struct drm
+               return -EINVAL;
+       }
+-      /* Ensure that the cursor is valid for the new mode before changing... */
+-      intel_crtc_update_cursor(crtc, true);
+-
+       if (is_lvds && dev_priv->lvds_downclock_avail) {
+               /*
+                * Ensure we match the reduced clock's P to the target clock.
+@@ -5688,9 +5685,6 @@ static int ironlake_crtc_mode_set(struct
+               intel_crtc->config.dpll.p2 = clock.p2;
+       }
+-      /* Ensure that the cursor is valid for the new mode before changing... */
+-      intel_crtc_update_cursor(crtc, true);
+-
+       /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
+       if (intel_crtc->config.has_pch_encoder) {
+               fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll);
+@@ -5897,9 +5891,6 @@ static int haswell_crtc_mode_set(struct
+       if (!intel_ddi_pll_mode_set(crtc))
+               return -EINVAL;
+-      /* Ensure that the cursor is valid for the new mode before changing... */
+-      intel_crtc_update_cursor(crtc, true);
+-
+       if (intel_crtc->config.has_dp_encoder)
+               intel_dp_set_m_n(intel_crtc);
diff --git a/queue-3.11/drm-i915-don-t-enable-the-cursor-on-a-disable-pipe.patch b/queue-3.11/drm-i915-don-t-enable-the-cursor-on-a-disable-pipe.patch
new file mode 100644 (file)
index 0000000..e3fb6e3
--- /dev/null
@@ -0,0 +1,47 @@
+From f2f5f771c5fc0fa252cde3d0d0452dcc785cc17a Mon Sep 17 00:00:00 2001
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Date: Tue, 17 Sep 2013 18:33:44 +0300
+Subject: drm/i915: Don't enable the cursor on a disable pipe
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit f2f5f771c5fc0fa252cde3d0d0452dcc785cc17a upstream.
+
+On HSW enabling a plane on a disabled pipe may hang the entire system.
+And there's no good reason for doing it ever, so just don't.
+
+v2: Move the crtc active checks to intel_crtc_cursor_{set,move} to
+    avoid confusing people during modeset
+
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Tested-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -6572,7 +6572,8 @@ static int intel_crtc_cursor_set(struct
+       intel_crtc->cursor_width = width;
+       intel_crtc->cursor_height = height;
+-      intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
++      if (intel_crtc->active)
++              intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
+       return 0;
+ fail_unpin:
+@@ -6591,7 +6592,8 @@ static int intel_crtc_cursor_move(struct
+       intel_crtc->cursor_x = x;
+       intel_crtc->cursor_y = y;
+-      intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
++      if (intel_crtc->active)
++              intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
+       return 0;
+ }
diff --git a/queue-3.11/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch b/queue-3.11/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch
new file mode 100644 (file)
index 0000000..74c2b99
--- /dev/null
@@ -0,0 +1,122 @@
+From 122f46badaafbe651f05c2c0f24cadee692f761b Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Wed, 4 Sep 2013 17:36:14 +0200
+Subject: drm/i915: fix gpu hang vs. flip stall deadlocks
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 122f46badaafbe651f05c2c0f24cadee692f761b upstream.
+
+Since we've started to clean up pending flips when the gpu hangs in
+
+commit 96a02917a0131e52efefde49c2784c0421d6c439
+Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Date:   Mon Feb 18 19:08:49 2013 +0200
+
+    drm/i915: Finish page flips and update primary planes after a GPU reset
+
+the gpu reset work now also grabs modeset locks. But since work items
+on our private work queue are not allowed to do that due to the
+flush_workqueue from the pageflip code this results in a neat
+deadlock:
+
+INFO: task kms_flip:14676 blocked for more than 120 seconds.
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+kms_flip        D ffff88019283a5c0     0 14676  13344 0x00000004
+ ffff88018e62dbf8 0000000000000046 ffff88013bdb12e0 ffff88018e62dfd8
+ ffff88018e62dfd8 00000000001d3b00 ffff88019283a5c0 ffff88018ec21000
+ ffff88018f693f00 ffff88018eece000 ffff88018e62dd60 ffff88018eece898
+Call Trace:
+ [<ffffffff8138ee7b>] schedule+0x60/0x62
+ [<ffffffffa046c0dd>] intel_crtc_wait_for_pending_flips+0xb2/0x114 [i915]
+ [<ffffffff81050ff4>] ? finish_wait+0x60/0x60
+ [<ffffffffa0478041>] intel_crtc_set_config+0x7f3/0x81e [i915]
+ [<ffffffffa031780a>] drm_mode_set_config_internal+0x4f/0xc6 [drm]
+ [<ffffffffa0319cf3>] drm_mode_setcrtc+0x44d/0x4f9 [drm]
+ [<ffffffff810e44da>] ? might_fault+0x38/0x86
+ [<ffffffffa030d51f>] drm_ioctl+0x2f9/0x447 [drm]
+ [<ffffffff8107a722>] ? trace_hardirqs_off+0xd/0xf
+ [<ffffffffa03198a6>] ? drm_mode_setplane+0x343/0x343 [drm]
+ [<ffffffff8112222f>] ? mntput_no_expire+0x3e/0x13d
+ [<ffffffff81117f33>] vfs_ioctl+0x18/0x34
+ [<ffffffff81118776>] do_vfs_ioctl+0x396/0x454
+ [<ffffffff81396b37>] ? sysret_check+0x1b/0x56
+ [<ffffffff81118886>] SyS_ioctl+0x52/0x7d
+ [<ffffffff81396b12>] system_call_fastpath+0x16/0x1b
+2 locks held by kms_flip/14676:
+ #0:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa0316545>] drm_modeset_lock_all+0x22/0x59 [drm]
+ #1:  (&crtc->mutex){+.+.+.}, at: [<ffffffffa031656b>] drm_modeset_lock_all+0x48/0x59 [drm]
+INFO: task kworker/u8:4:175 blocked for more than 120 seconds.
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+kworker/u8:4    D ffff88018de9a5c0     0   175      2 0x00000000
+Workqueue: i915 i915_error_work_func [i915]
+ ffff88018e37dc30 0000000000000046 ffff8801938ab8a0 ffff88018e37dfd8
+ ffff88018e37dfd8 00000000001d3b00 ffff88018de9a5c0 ffff88018ec21018
+ 0000000000000246 ffff88018e37dca0 000000005a865a86 ffff88018de9a5c0
+Call Trace:
+ [<ffffffff8138ee7b>] schedule+0x60/0x62
+ [<ffffffff8138f23d>] schedule_preempt_disabled+0x9/0xb
+ [<ffffffff8138d0cd>] mutex_lock_nested+0x205/0x3b1
+ [<ffffffffa0477094>] ? intel_display_handle_reset+0x7e/0xbd [i915]
+ [<ffffffffa0477094>] ? intel_display_handle_reset+0x7e/0xbd [i915]
+ [<ffffffffa0477094>] intel_display_handle_reset+0x7e/0xbd [i915]
+ [<ffffffffa044e0a2>] i915_error_work_func+0x128/0x147 [i915]
+ [<ffffffff8104a89a>] process_one_work+0x1d4/0x35a
+ [<ffffffff8104a821>] ? process_one_work+0x15b/0x35a
+ [<ffffffff8104b4a5>] worker_thread+0x144/0x1f0
+ [<ffffffff8104b361>] ? rescuer_thread+0x275/0x275
+ [<ffffffff8105076d>] kthread+0xac/0xb4
+ [<ffffffff81059d30>] ? finish_task_switch+0x3b/0xc0
+ [<ffffffff810506c1>] ? __kthread_parkme+0x60/0x60
+ [<ffffffff81396a6c>] ret_from_fork+0x7c/0xb0
+ [<ffffffff810506c1>] ? __kthread_parkme+0x60/0x60
+3 locks held by kworker/u8:4/175:
+ #0:  (i915){.+.+.+}, at: [<ffffffff8104a821>] process_one_work+0x15b/0x35a
+ #1:  ((&dev_priv->gpu_error.work)){+.+.+.}, at: [<ffffffff8104a821>] process_one_work+0x15b/0x35a
+ #2:  (&crtc->mutex){+.+.+.}, at: [<ffffffffa0477094>] intel_display_handle_reset+0x7e/0xbd [i915]
+
+This blew up while running kms_flip/flip-vs-panning-vs-hang-interruptible
+on one of my older machines.
+
+Unfortunately (despite the proper lockdep annotations for
+flush_workqueue) lockdep still doesn't detect this correctly, so we
+need to rely on chance to discover these bugs.
+
+Apply the usual bugfix and schedule the reset work on the system
+workqueue to keep our own driver workqueue free of any modeset lock
+grabbing.
+
+Note that this is not a terribly serious regression since before the
+offending commit we'd simply have stalled userspace forever due to
+failing to abort all outstanding pageflips.
+
+v2: Add a comment as requested by Chris.
+
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_irq.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -2127,7 +2127,13 @@ void i915_handle_error(struct drm_device
+                       wake_up_all(&ring->irq_queue);
+       }
+-      queue_work(dev_priv->wq, &dev_priv->gpu_error.work);
++      /*
++       * Our reset work can grab modeset locks (since it needs to reset the
++       * state of outstanding pagelips). Hence it must not be run on our own
++       * dev-priv->wq work queue for otherwise the flush_work in the pageflip
++       * code will deadlock.
++       */
++      schedule_work(&dev_priv->gpu_error.work);
+ }
+ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe)
diff --git a/queue-3.11/drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip-code-deadlock.patch b/queue-3.11/drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip-code-deadlock.patch
new file mode 100644 (file)
index 0000000..91ab799
--- /dev/null
@@ -0,0 +1,87 @@
+From 645416f5adc87c8fae44289cdba7562f3ade8f5c Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Mon, 2 Sep 2013 16:22:25 +0200
+Subject: drm/i915: fix hpd work vs. flush_work in the pageflip code deadlock
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 645416f5adc87c8fae44289cdba7562f3ade8f5c upstream.
+
+Historically we've run our own driver hotplug handling in our own
+work-queue, which then launched the drm core hotplug handling in the
+system workqueue. This is important since we flush our own driver
+workqueue in the pageflip code while hodling modeset locks, and only
+the drm hotplug code grabbed these locks. But with
+
+commit 69787f7da6b2adc4054357a661aaa1701a9ca76f
+Author: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date:   Tue Oct 23 18:23:34 2012 +0000
+
+    drm: run the hpd irq event code directly
+
+this was changed and now we could deadlock in our flip handler if
+there's a hotplug work blocking the progress of the crucial unpin
+works. So this broke the careful deadlock avoidance implemented in
+
+commit b4a98e57fc27854b5938fc8b08b68e5e68b91e1f
+Author: Chris Wilson <chris@chris-wilson.co.uk>
+Date:   Thu Nov 1 09:26:26 2012 +0000
+
+    drm/i915: Flush outstanding unpin tasks before pageflipping
+
+Since the rule thus far has been that work items on our own workqueue
+may never grab modeset locks simply restore that rule again.
+
+v2: Add a comment to the declaration of dev_priv->wq to warn readers
+about the tricky implications of using it. Suggested by Chris Wilson.
+
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Stuart Abercrombie <sabercrombie@chromium.org>
+Reported-by: Stuart Abercrombie <sabercrombie@chromium.org>
+References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/26239
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+[danvet: Squash in a comment at the place where we schedule the work.
+Requested after-the-fact by Chris on irc since the hpd work isn't the
+only place we botch this.]
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_drv.h |    7 +++++++
+ drivers/gpu/drm/i915/i915_irq.c |    9 +++++++--
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1091,6 +1091,13 @@ typedef struct drm_i915_private {
+       unsigned int fsb_freq, mem_freq, is_ddr3;
++      /**
++       * wq - Driver workqueue for GEM.
++       *
++       * NOTE: Work items scheduled here are not allowed to grab any modeset
++       * locks, for otherwise the flushing done in the pageflip code will
++       * result in deadlocks.
++       */
+       struct workqueue_struct *wq;
+       /* Display functions */
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -910,8 +910,13 @@ static inline void intel_hpd_irq_handler
+               dev_priv->display.hpd_irq_setup(dev);
+       spin_unlock(&dev_priv->irq_lock);
+-      queue_work(dev_priv->wq,
+-                 &dev_priv->hotplug_work);
++      /*
++       * Our hotplug handler can grab modeset locks (by calling down into the
++       * fb helpers). Hence it must not be run on our own dev-priv->wq work
++       * queue for otherwise the flush_work in the pageflip code will
++       * deadlock.
++       */
++      schedule_work(&dev_priv->hotplug_work);
+ }
+ static void gmbus_irq_handler(struct drm_device *dev)
diff --git a/queue-3.11/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch b/queue-3.11/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch
new file mode 100644 (file)
index 0000000..85a7909
--- /dev/null
@@ -0,0 +1,196 @@
+From 17e1df07df0fbc77696a1e1b6ccf9f2e5af70e40 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Sun, 8 Sep 2013 21:57:13 +0200
+Subject: drm/i915: fix wait_for_pending_flips vs gpu hang deadlock
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 17e1df07df0fbc77696a1e1b6ccf9f2e5af70e40 upstream.
+
+My g33 here seems to be shockingly good at hitting them all. This time
+around kms_flip/flip-vs-panning-vs-hang blows up:
+
+intel_crtc_wait_for_pending_flips correctly checks for gpu hangs and
+if a gpu hang is pending aborts the wait for outstanding flips so that
+the setcrtc call will succeed and release the crtc mutex. And the gpu
+hang handler needs that lock in intel_display_handle_reset to be able
+to complete outstanding flips.
+
+The problem is that we can race in two ways:
+- Waiters on the dev_priv->pending_flip_queue aren't woken up after
+  we've the reset as pending, but before we actually start the reset
+  work. This means that the waiter doesn't notice the pending reset
+  and hence will keep on hogging the locks.
+
+  Like with dev->struct_mutex and the ring->irq_queue wait queues we
+  there need to wake up everyone that potentially holds a lock which
+  the reset handler needs.
+
+- intel_display_handle_reset was called _after_ we've already
+  signalled the completion of the reset work. Which means a waiter
+  could sneak in, grab the lock and never release it (since the
+  pageflips won't ever get released).
+
+  Similar to resetting the gem state all the reset work must complete
+  before we update the reset counter. Contrary to the gem reset we
+  don't need to have a second explicit wake up call since that will
+  have happened already when completing the pageflips. We also don't
+  have any issues that the completion happens while the reset state is
+  still pending - wait_for_pending_flips is only there to ensure we
+  display the right frame. After a gpu hang&reset events such
+  guarantees are out the window anyway. This is in contrast to the gem
+  code where too-early wake-up would result in unnecessary restarting
+  of ioctls.
+
+Also, since we've gotten these various deadlocks and ordering
+constraints wrong so often throw copious amounts of comments at the
+code.
+
+This deadlock regression has been introduced in the commit which added
+the pageflip reset logic to the gpu hang work:
+
+commit 96a02917a0131e52efefde49c2784c0421d6c439
+Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Date:   Mon Feb 18 19:08:49 2013 +0200
+
+    drm/i915: Finish page flips and update primary planes after a GPU reset
+
+v2:
+- Add comments to explain how the wake_up serves as memory barriers
+  for the atomic_t reset counter.
+- Improve the comments a bit as suggested by Chris Wilson.
+- Extract the wake_up calls before/after the reset into a little
+  i915_error_wake_up and unconditionally wake up the
+  pending_flip_queue waiters, again as suggested by Chris Wilson.
+
+v3: Throw copious amounts of comments at i915_error_wake_up as
+suggested by Chris Wilson.
+
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_irq.c |   68 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 54 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -1407,6 +1407,34 @@ done:
+       return ret;
+ }
++static void i915_error_wake_up(struct drm_i915_private *dev_priv,
++                             bool reset_completed)
++{
++      struct intel_ring_buffer *ring;
++      int i;
++
++      /*
++       * Notify all waiters for GPU completion events that reset state has
++       * been changed, and that they need to restart their wait after
++       * checking for potential errors (and bail out to drop locks if there is
++       * a gpu reset pending so that i915_error_work_func can acquire them).
++       */
++
++      /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */
++      for_each_ring(ring, dev_priv, i)
++              wake_up_all(&ring->irq_queue);
++
++      /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */
++      wake_up_all(&dev_priv->pending_flip_queue);
++
++      /*
++       * Signal tasks blocked in i915_gem_wait_for_error that the pending
++       * reset state is cleared.
++       */
++      if (reset_completed)
++              wake_up_all(&dev_priv->gpu_error.reset_queue);
++}
++
+ /**
+  * i915_error_work_func - do process context error handling work
+  * @work: work struct
+@@ -1421,11 +1449,10 @@ static void i915_error_work_func(struct
+       drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t,
+                                                   gpu_error);
+       struct drm_device *dev = dev_priv->dev;
+-      struct intel_ring_buffer *ring;
+       char *error_event[] = { "ERROR=1", NULL };
+       char *reset_event[] = { "RESET=1", NULL };
+       char *reset_done_event[] = { "ERROR=0", NULL };
+-      int i, ret;
++      int ret;
+       kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
+@@ -1444,8 +1471,16 @@ static void i915_error_work_func(struct
+               kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE,
+                                  reset_event);
++              /*
++               * All state reset _must_ be completed before we update the
++               * reset counter, for otherwise waiters might miss the reset
++               * pending state and not properly drop locks, resulting in
++               * deadlocks with the reset work.
++               */
+               ret = i915_reset(dev);
++              intel_display_handle_reset(dev);
++
+               if (ret == 0) {
+                       /*
+                        * After all the gem state is reset, increment the reset
+@@ -1466,12 +1501,11 @@ static void i915_error_work_func(struct
+                       atomic_set(&error->reset_counter, I915_WEDGED);
+               }
+-              for_each_ring(ring, dev_priv, i)
+-                      wake_up_all(&ring->irq_queue);
+-
+-              intel_display_handle_reset(dev);
+-
+-              wake_up_all(&dev_priv->gpu_error.reset_queue);
++              /*
++               * Note: The wake_up also serves as a memory barrier so that
++               * waiters see the update value of the reset counter atomic_t.
++               */
++              i915_error_wake_up(dev_priv, true);
+       }
+ }
+@@ -2109,8 +2143,6 @@ static void i915_report_and_clear_eir(st
+ void i915_handle_error(struct drm_device *dev, bool wedged)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+-      struct intel_ring_buffer *ring;
+-      int i;
+       i915_capture_error_state(dev);
+       i915_report_and_clear_eir(dev);
+@@ -2120,11 +2152,19 @@ void i915_handle_error(struct drm_device
+                               &dev_priv->gpu_error.reset_counter);
+               /*
+-               * Wakeup waiting processes so that the reset work item
+-               * doesn't deadlock trying to grab various locks.
++               * Wakeup waiting processes so that the reset work function
++               * i915_error_work_func doesn't deadlock trying to grab various
++               * locks. By bumping the reset counter first, the woken
++               * processes will see a reset in progress and back off,
++               * releasing their locks and then wait for the reset completion.
++               * We must do this for _all_ gpu waiters that might hold locks
++               * that the reset work needs to acquire.
++               *
++               * Note: The wake_up serves as the required memory barrier to
++               * ensure that the waiters see the updated value of the reset
++               * counter atomic_t.
+                */
+-              for_each_ring(ring, dev_priv, i)
+-                      wake_up_all(&ring->irq_queue);
++              i915_error_wake_up(dev_priv, false);
+       }
+       /*
diff --git a/queue-3.11/drm-i915-try-not-to-lose-backlight-cblv-precision.patch b/queue-3.11/drm-i915-try-not-to-lose-backlight-cblv-precision.patch
new file mode 100644 (file)
index 0000000..547b91c
--- /dev/null
@@ -0,0 +1,46 @@
+From cac6a5ae0118832936eb162ec4cedb30f2422bcc Mon Sep 17 00:00:00 2001
+From: Jani Nikula <jani.nikula@intel.com>
+Date: Fri, 23 Aug 2013 10:50:39 +0300
+Subject: drm/i915: try not to lose backlight CBLV precision
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+commit cac6a5ae0118832936eb162ec4cedb30f2422bcc upstream.
+
+ACPI has _BCM and _BQC methods to set and query the backlight
+brightness, respectively. The ACPI opregion has variables BCLP and CBLV
+to hold the requested and current backlight brightness, respectively.
+
+The BCLP variable has range 0..255 while the others have range
+0..100. This means the _BCM method has to scale the brightness for BCLP,
+and the gfx driver has to scale the requested value back for CBLV. If
+the _BQC method uses the CBLV variable (apparently some implementations
+do, some don't) for current backlight level reporting, there's room for
+rounding errors.
+
+Use DIV_ROUND_UP for scaling back to CBLV to get back to the same values
+that were passed to _BCM, presuming the _BCM simply uses bclp = (in *
+255) / 100 for scaling to BCLP.
+
+Reference: https://gist.github.com/aaronlu/6314920
+Reported-by: Aaron Lu <aaron.lu@intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Reviewed-by: Aaron Lu <aaron.lu@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_opregion.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/intel_opregion.c
++++ b/drivers/gpu/drm/i915/intel_opregion.c
+@@ -173,7 +173,7 @@ static u32 asle_set_backlight(struct drm
+               return ASLE_BACKLIGHT_FAILED;
+       intel_panel_set_backlight(dev, bclp, 255);
+-      iowrite32((bclp*0x64)/0xff | ASLE_CBLV_VALID, &asle->cblv);
++      iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
+       return 0;
+ }
diff --git a/queue-3.11/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch b/queue-3.11/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch
new file mode 100644 (file)
index 0000000..2d50b77
--- /dev/null
@@ -0,0 +1,43 @@
+From 182b17c8dc4e83aab000ce86587b6810e515da87 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Tue, 17 Sep 2013 14:21:15 +1000
+Subject: drm/ttm: fix the tt_populated check in ttm_tt_destroy()
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 182b17c8dc4e83aab000ce86587b6810e515da87 upstream.
+
+After a vmalloc failure in ttm_dma_tt_alloc_page_directory(),
+ttm_dma_tt_init() will call ttm_tt_destroy() to cleanup, and end up
+inside the driver's unpopulate() hook when populate() has never yet
+been called.
+
+On nouveau, the first issue to be hit because of this is that
+dma_address[] may be a NULL pointer.  After working around this,
+ttm_pool_unpopulate() may potentially hit the same issue with
+the pages[] array.
+
+It seems to make more sense to avoid calling unpopulate on already
+unpopulated TTMs than to add checks to all the implementations.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ttm/ttm_tt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/ttm/ttm_tt.c
++++ b/drivers/gpu/drm/ttm/ttm_tt.c
+@@ -170,7 +170,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
+               ttm_tt_unbind(ttm);
+       }
+-      if (likely(ttm->pages != NULL)) {
++      if (ttm->state == tt_unbound) {
+               ttm->bdev->driver->ttm_tt_unpopulate(ttm);
+       }
diff --git a/queue-3.11/radeon-kms-fix-uninitialised-hotplug-work-usage-in-r100_irq_process.patch b/queue-3.11/radeon-kms-fix-uninitialised-hotplug-work-usage-in-r100_irq_process.patch
new file mode 100644 (file)
index 0000000..cbd6ec2
--- /dev/null
@@ -0,0 +1,104 @@
+From 27c505ca84e164ec66ad55dcf3f5befaac83f10a Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Date: Thu, 29 Aug 2013 12:29:35 +0300
+Subject: radeon kms: fix uninitialised hotplug work usage in r100_irq_process()
+
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+
+commit 27c505ca84e164ec66ad55dcf3f5befaac83f10a upstream.
+
+Commit a01c34f72e7cd2624570818f579b5ab464f93de2 (radeon kms: do not
+flush uninitialized hotplug work) moved work initialisation phase to
+the last step of radeon_irq_kms_init(). Meelis Roos reported that this
+causes problems on his machine because drm_irq_install() uses hotplug
+work on r100.
+
+hotplug work flushed in radeon_irq_kms_fini(), with two possible cases:
+-- radeon_irq_kms_fini() call after successful radeon_irq_kms_init()
+-- radeon_irq_kms_fini() call after unsuccessful (or not called at all)
+   radeon_irq_kms_init()
+
+The latter one causes flush work on uninitialised hotplug work. Move
+work initialisation before drm_irq_install(), but keep existing agreement
+to flush hotplug work in radeon_irq_kms_fini() only for `irq.installed'
+(successful radeon_irq_kms_init()) case.
+
+WARNING: CPU: 0 PID: 243 at kernel/workqueue.c:1378 __queue_work+0x132/0x16d()
+Call Trace:
+[<c12319b3>] ? dump_stack+0xa/0x13
+[<c1022600>] ? warn_slowpath_common+0x75/0x8a
+[<c1031010>] ? __queue_work+0x132/0x16d
+[<c1031010>] ? __queue_work+0x132/0x16d
+[<c102269e>] ? warn_slowpath_null+0x1b/0x1f
+[<c1031010>] ? __queue_work+0x132/0x16d
+[<c103107b>] ? queue_work_on+0x30/0x40
+[<f8aed3f3>] ? r100_irq_process+0x16d/0x1e6 [radeon]
+[<f8ae77cf>] ? radeon_driver_irq_preinstall_kms+0xc2/0xc5 [radeon]
+[<f8974d77>] ? drm_irq_install+0xb2/0x1ac [drm]
+[<f897604d>] ? drm_vblank_init+0x196/0x1d2 [drm]
+[<f8ae78d3>] ? radeon_irq_kms_init+0x33/0xc6 [radeon]
+[<f8aef35a>] ? r100_startup+0x1a3/0x1d6 [radeon]
+[<f8ad77c8>] ? radeon_ttm_init+0x26e/0x287 [radeon]
+[<f8aef752>] ? r100_init+0x2b3/0x309 [radeon]
+[<c118082e>] ? vga_client_register+0x39/0x40
+[<f8ac535f>] ? radeon_device_init+0x54b/0x61b [radeon]
+[<f8ac40fd>] ? cail_mc_write+0x13/0x13 [radeon]
+[<f8ac6864>] ? radeon_driver_load_kms+0x82/0xda [radeon]
+[<f8978bbd>] ? drm_get_pci_dev+0x136/0x22d [drm]
+[<f8ac409b>] ? radeon_pci_probe+0x6c/0x86 [radeon]
+[<c112acf6>] ? pci_device_probe+0x4c/0x83
+[<c11846c7>] ? driver_probe_device+0x80/0x184
+[<c112a848>] ? pci_match_id+0x18/0x36
+[<c1184837>] ? __driver_attach+0x44/0x5f
+[<c11833f4>] ? bus_for_each_dev+0x50/0x5a
+[<c118433e>] ? driver_attach+0x14/0x16
+[<c11847f3>] ? __device_attach+0x28/0x28
+[<c1184045>] ? bus_add_driver+0xd6/0x1bf
+[<c1184c22>] ? driver_register+0x78/0xcf
+[<f8ba8000>] ? 0xf8ba7fff
+[<c10003bf>] ? do_one_initcall+0x8b/0x121
+[<c101e668>] ? change_page_attr_clear+0x2e/0x33
+[<f8ba8000>] ? 0xf8ba7fff
+[<c101e689>] ? set_memory_ro+0x1c/0x20
+[<c104de94>] ? set_page_attributes+0x11/0x12
+[<c104f6e1>] ? load_module+0x12fa/0x17e8
+[<c107483b>] ? map_vm_area+0x22/0x31
+[<c104fc36>] ? SyS_init_module+0x67/0x7d
+[<c1234245>] ? sysenter_do_call+0x12/0x26
+
+Reported-by: Meelis Roos <mroos@linux.ee>
+Tested-by: Meelis Roos <mroos@linux.ee>
+Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_irq_kms.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+@@ -275,17 +275,19 @@ int radeon_irq_kms_init(struct radeon_de
+                       dev_info(rdev->dev, "radeon: using MSI.\n");
+               }
+       }
++
++      INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
++      INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
++      INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func);
++
+       rdev->irq.installed = true;
+       r = drm_irq_install(rdev->ddev);
+       if (r) {
+               rdev->irq.installed = false;
++              flush_work(&rdev->hotplug_work);
+               return r;
+       }
+-      INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
+-      INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
+-      INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func);
+-
+       DRM_INFO("radeon: irq initialized.\n");
+       return 0;
+ }
index d2ecc4cbc16314d25319fad278782a9707098935..982ceb3d4ec294baf2a5f1569a1aaace46299245 100644 (file)
@@ -19,3 +19,13 @@ hid-sony-validate-hid-output-report-details.patch
 hid-lenovo-tpkbd-validate-output-report-details.patch
 hid-logitech-dj-validate-output-report-details.patch
 usb-gadget-fix-a-bug-and-a-warn_on-in-dummy-hcd.patch
+drm-i915-try-not-to-lose-backlight-cblv-precision.patch
+drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip-code-deadlock.patch
+drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch
+drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch
+drm-i915-do-not-update-cursor-in-crtc-mode-set.patch
+drm-i915-don-t-enable-the-cursor-on-a-disable-pipe.patch
+drm-fix-drm_ioctl_mode_getfb-handle-leak.patch
+drm-ast-fix-the-ast-open-key-function.patch
+drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch
+radeon-kms-fix-uninitialised-hotplug-work-usage-in-r100_irq_process.patch