From: Greg Kroah-Hartman Date: Fri, 27 Sep 2013 22:02:17 +0000 (-0700) Subject: 3.11-stable patches X-Git-Tag: v3.0.98~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1bd3305a43ab385f34e2090056d03ee859514c36;p=thirdparty%2Fkernel%2Fstable-queue.git 3.11-stable patches 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 --- 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 index 00000000000..c6eed881309 --- /dev/null +++ b/queue-3.11/drm-ast-fix-the-ast-open-key-function.patch @@ -0,0 +1,31 @@ +From 2e8378136f28bea960cec643d3fa5d843c9049ec Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 12 Sep 2013 15:31:04 +1000 +Subject: drm/ast: fix the ast open key function + +From: Dave Airlie + +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 +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c31a42c4506 --- /dev/null +++ b/queue-3.11/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch @@ -0,0 +1,75 @@ +From 101b96f32956ee99bf1468afaf572b88cda9f88b Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Mon, 26 Aug 2013 15:16:49 +0200 +Subject: drm: fix DRM_IOCTL_MODE_GETFB handle-leak + +From: David Herrmann + +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 + 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 +Reviewed-by: Chris Wilson +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b52d90cf81c --- /dev/null +++ b/queue-3.11/drm-i915-do-not-update-cursor-in-crtc-mode-set.patch @@ -0,0 +1,61 @@ +From cc173961a68034c1171a421f0dbed39edfb60880 Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Tue, 17 Sep 2013 18:33:43 +0300 +Subject: drm/i915: do not update cursor in crtc mode set + +From: Jani Nikula + +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ä +Reviewed-by: Ville Syrjälä +Signed-off-by: Jani Nikula +Tested-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e3fb6e3d74f --- /dev/null +++ b/queue-3.11/drm-i915-don-t-enable-the-cursor-on-a-disable-pipe.patch @@ -0,0 +1,47 @@ +From f2f5f771c5fc0fa252cde3d0d0452dcc785cc17a Mon Sep 17 00:00:00 2001 +From: Ville Syrjälä +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ä + +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ä +Tested-by: Paulo Zanoni +Reviewed-by: Paulo Zanoni +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..74c2b99fc98 --- /dev/null +++ b/queue-3.11/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch @@ -0,0 +1,122 @@ +From 122f46badaafbe651f05c2c0f24cadee692f761b Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Wed, 4 Sep 2013 17:36:14 +0200 +Subject: drm/i915: fix gpu hang vs. flip stall deadlocks + +From: Daniel Vetter + +commit 122f46badaafbe651f05c2c0f24cadee692f761b upstream. + +Since we've started to clean up pending flips when the gpu hangs in + +commit 96a02917a0131e52efefde49c2784c0421d6c439 +Author: Ville Syrjälä +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: + [] schedule+0x60/0x62 + [] intel_crtc_wait_for_pending_flips+0xb2/0x114 [i915] + [] ? finish_wait+0x60/0x60 + [] intel_crtc_set_config+0x7f3/0x81e [i915] + [] drm_mode_set_config_internal+0x4f/0xc6 [drm] + [] drm_mode_setcrtc+0x44d/0x4f9 [drm] + [] ? might_fault+0x38/0x86 + [] drm_ioctl+0x2f9/0x447 [drm] + [] ? trace_hardirqs_off+0xd/0xf + [] ? drm_mode_setplane+0x343/0x343 [drm] + [] ? mntput_no_expire+0x3e/0x13d + [] vfs_ioctl+0x18/0x34 + [] do_vfs_ioctl+0x396/0x454 + [] ? sysret_check+0x1b/0x56 + [] SyS_ioctl+0x52/0x7d + [] system_call_fastpath+0x16/0x1b +2 locks held by kms_flip/14676: + #0: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x22/0x59 [drm] + #1: (&crtc->mutex){+.+.+.}, at: [] 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: + [] schedule+0x60/0x62 + [] schedule_preempt_disabled+0x9/0xb + [] mutex_lock_nested+0x205/0x3b1 + [] ? intel_display_handle_reset+0x7e/0xbd [i915] + [] ? intel_display_handle_reset+0x7e/0xbd [i915] + [] intel_display_handle_reset+0x7e/0xbd [i915] + [] i915_error_work_func+0x128/0x147 [i915] + [] process_one_work+0x1d4/0x35a + [] ? process_one_work+0x15b/0x35a + [] worker_thread+0x144/0x1f0 + [] ? rescuer_thread+0x275/0x275 + [] kthread+0xac/0xb4 + [] ? finish_task_switch+0x3b/0xc0 + [] ? __kthread_parkme+0x60/0x60 + [] ret_from_fork+0x7c/0xb0 + [] ? __kthread_parkme+0x60/0x60 +3 locks held by kworker/u8:4/175: + #0: (i915){.+.+.+}, at: [] process_one_work+0x15b/0x35a + #1: ((&dev_priv->gpu_error.work)){+.+.+.}, at: [] process_one_work+0x15b/0x35a + #2: (&crtc->mutex){+.+.+.}, at: [] 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 +Cc: Ville Syrjälä +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..91ab799ba14 --- /dev/null +++ b/queue-3.11/drm-i915-fix-hpd-work-vs.-flush_work-in-the-pageflip-code-deadlock.patch @@ -0,0 +1,87 @@ +From 645416f5adc87c8fae44289cdba7562f3ade8f5c Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +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 + +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 +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 +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 +Cc: Stuart Abercrombie +Reported-by: Stuart Abercrombie +References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/26239 +Reviewed-by: Chris Wilson +[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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..85a7909abb8 --- /dev/null +++ b/queue-3.11/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch @@ -0,0 +1,196 @@ +From 17e1df07df0fbc77696a1e1b6ccf9f2e5af70e40 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sun, 8 Sep 2013 21:57:13 +0200 +Subject: drm/i915: fix wait_for_pending_flips vs gpu hang deadlock + +From: Daniel Vetter + +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ä +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ä +Cc: Chris Wilson +Reviewed-by: Chris Wilson +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..547b91c20a6 --- /dev/null +++ b/queue-3.11/drm-i915-try-not-to-lose-backlight-cblv-precision.patch @@ -0,0 +1,46 @@ +From cac6a5ae0118832936eb162ec4cedb30f2422bcc Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Fri, 23 Aug 2013 10:50:39 +0300 +Subject: drm/i915: try not to lose backlight CBLV precision + +From: Jani Nikula + +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 +Signed-off-by: Jani Nikula +Reviewed-by: Aaron Lu +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2d50b77e1b5 --- /dev/null +++ b/queue-3.11/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch @@ -0,0 +1,43 @@ +From 182b17c8dc4e83aab000ce86587b6810e515da87 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Tue, 17 Sep 2013 14:21:15 +1000 +Subject: drm/ttm: fix the tt_populated check in ttm_tt_destroy() + +From: Ben Skeggs + +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 +Reviewed-by: Thomas Hellstrom +Cc: Jerome Glisse +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cbd6ec25cbd --- /dev/null +++ b/queue-3.11/radeon-kms-fix-uninitialised-hotplug-work-usage-in-r100_irq_process.patch @@ -0,0 +1,104 @@ +From 27c505ca84e164ec66ad55dcf3f5befaac83f10a Mon Sep 17 00:00:00 2001 +From: Sergey Senozhatsky +Date: Thu, 29 Aug 2013 12:29:35 +0300 +Subject: radeon kms: fix uninitialised hotplug work usage in r100_irq_process() + +From: Sergey Senozhatsky + +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: +[] ? dump_stack+0xa/0x13 +[] ? warn_slowpath_common+0x75/0x8a +[] ? __queue_work+0x132/0x16d +[] ? __queue_work+0x132/0x16d +[] ? warn_slowpath_null+0x1b/0x1f +[] ? __queue_work+0x132/0x16d +[] ? queue_work_on+0x30/0x40 +[] ? r100_irq_process+0x16d/0x1e6 [radeon] +[] ? radeon_driver_irq_preinstall_kms+0xc2/0xc5 [radeon] +[] ? drm_irq_install+0xb2/0x1ac [drm] +[] ? drm_vblank_init+0x196/0x1d2 [drm] +[] ? radeon_irq_kms_init+0x33/0xc6 [radeon] +[] ? r100_startup+0x1a3/0x1d6 [radeon] +[] ? radeon_ttm_init+0x26e/0x287 [radeon] +[] ? r100_init+0x2b3/0x309 [radeon] +[] ? vga_client_register+0x39/0x40 +[] ? radeon_device_init+0x54b/0x61b [radeon] +[] ? cail_mc_write+0x13/0x13 [radeon] +[] ? radeon_driver_load_kms+0x82/0xda [radeon] +[] ? drm_get_pci_dev+0x136/0x22d [drm] +[] ? radeon_pci_probe+0x6c/0x86 [radeon] +[] ? pci_device_probe+0x4c/0x83 +[] ? driver_probe_device+0x80/0x184 +[] ? pci_match_id+0x18/0x36 +[] ? __driver_attach+0x44/0x5f +[] ? bus_for_each_dev+0x50/0x5a +[] ? driver_attach+0x14/0x16 +[] ? __device_attach+0x28/0x28 +[] ? bus_add_driver+0xd6/0x1bf +[] ? driver_register+0x78/0xcf +[] ? 0xf8ba7fff +[] ? do_one_initcall+0x8b/0x121 +[] ? change_page_attr_clear+0x2e/0x33 +[] ? 0xf8ba7fff +[] ? set_memory_ro+0x1c/0x20 +[] ? set_page_attributes+0x11/0x12 +[] ? load_module+0x12fa/0x17e8 +[] ? map_vm_area+0x22/0x31 +[] ? SyS_init_module+0x67/0x7d +[] ? sysenter_do_call+0x12/0x26 + +Reported-by: Meelis Roos +Tested-by: Meelis Roos +Signed-off-by: Sergey Senozhatsky +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-3.11/series b/queue-3.11/series index d2ecc4cbc16..982ceb3d4ec 100644 --- a/queue-3.11/series +++ b/queue-3.11/series @@ -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