From b87cf9aad89e4d6a1d2c6405a33a938d0ba1ca68 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 1 Mar 2016 13:24:39 -0800 Subject: [PATCH] 4.4-stable patches added patches: drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch drm-qxl-use-kmalloc_array-to-alloc-reloc_info-in-qxl_process_single_command.patch drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch drm-radeon-pm-adjust-display-configuration-after-powerstate.patch drm-radeon-use-post-decrement-in-error-handling.patch make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch --- ...st_modeset-regression-from-linux-4.4.patch | 83 ++++++++++++ ..._vblank_offdelay-in-drm_vblank_on-v2.patch | 65 ++++++++++ ...redundant-calls-to-drm_vblank_off-v2.patch | 75 +++++++++++ ...mps-1-with-active-vblank-clients.-v2.patch | 122 ++++++++++++++++++ ...c_info-in-qxl_process_single_command.patch | 34 +++++ ..._flip_work_func-on-disabled-crtc.-v2.patch | 109 ++++++++++++++++ ...splay-configuration-after-powerstate.patch | 49 +++++++ ...use-post-decrement-in-error-handling.patch | 36 ++++++ ...g-shmem-fast-symlinks-is-rcu-delayed.patch | 67 ++++++++++ queue-4.4/series | 9 ++ 10 files changed, 649 insertions(+) create mode 100644 queue-4.4/drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch create mode 100644 queue-4.4/drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch create mode 100644 queue-4.4/drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch create mode 100644 queue-4.4/drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch create mode 100644 queue-4.4/drm-qxl-use-kmalloc_array-to-alloc-reloc_info-in-qxl_process_single_command.patch create mode 100644 queue-4.4/drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch create mode 100644 queue-4.4/drm-radeon-pm-adjust-display-configuration-after-powerstate.patch create mode 100644 queue-4.4/drm-radeon-use-post-decrement-in-error-handling.patch create mode 100644 queue-4.4/make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch diff --git a/queue-4.4/drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch b/queue-4.4/drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch new file mode 100644 index 00000000000..69f9ff22411 --- /dev/null +++ b/queue-4.4/drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch @@ -0,0 +1,83 @@ +From c61934ed9a0e3911a9935df26858726a7ec35ec0 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Fri, 12 Feb 2016 20:30:29 +0100 +Subject: drm: Fix drm_vblank_pre/post_modeset regression from Linux 4.4 + +From: Mario Kleiner + +commit c61934ed9a0e3911a9935df26858726a7ec35ec0 upstream. + +Changes to drm_update_vblank_count() in Linux 4.4 broke the +behaviour of the pre/post modeset functions as the new update +code doesn't deal with hw vblank counter resets inbetween calls +to drm_vblank_pre_modeset an drm_vblank_post_modeset, as it +should. + +This causes mistreatment of such hw counter resets as counter +wraparound, and thereby large forward jumps of the software +vblank counter which in turn cause vblank event dispatching +and vblank waits to fail/hang --> userspace clients hang. + +This symptom was reported on radeon-kms to cause a infinite +hang of KDE Plasma 5 shell's login procedure, preventing users +from logging in. + +Fix this by detecting when drm_update_vblank_count() is called +inside a pre->post modeset interval. If so, clamp valid vblank +increments to the safe values 0 and 1, pretty much restoring +the update behavior of the old update code of Linux 4.3 and +earlier. Also reset the last recorded hw vblank count at call +to drm_vblank_post_modeset() to be safe against hw that after +modesetting, dpms on etc. only fires its first vblank irq after +drm_vblank_post_modeset() was already called. + +Reported-by: Vlastimil Babka +Signed-off-by: Mario Kleiner +Reviewed-by: Daniel Vetter +Tested-by: Vlastimil Babka +Cc: michel@daenzer.net +Cc: vbabka@suse.cz +Cc: ville.syrjala@linux.intel.com +Cc: daniel.vetter@ffwll.ch +Cc: dri-devel@lists.freedesktop.org +Cc: alexander.deucher@amd.com +Cc: christian.koenig@amd.com +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_irq.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/gpu/drm/drm_irq.c ++++ b/drivers/gpu/drm/drm_irq.c +@@ -222,6 +222,21 @@ static void drm_update_vblank_count(stru + } + + /* ++ * Within a drm_vblank_pre_modeset - drm_vblank_post_modeset ++ * interval? If so then vblank irqs keep running and it will likely ++ * happen that the hardware vblank counter is not trustworthy as it ++ * might reset at some point in that interval and vblank timestamps ++ * are not trustworthy either in that interval. Iow. this can result ++ * in a bogus diff >> 1 which must be avoided as it would cause ++ * random large forward jumps of the software vblank counter. ++ */ ++ if (diff > 1 && (vblank->inmodeset & 0x2)) { ++ DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u" ++ " due to pre-modeset.\n", pipe, diff); ++ diff = 1; ++ } ++ ++ /* + * FIMXE: Need to replace this hack with proper seqlocks. + * + * Restrict the bump of the software vblank counter to a safe maximum +@@ -1575,6 +1590,7 @@ void drm_vblank_post_modeset(struct drm_ + if (vblank->inmodeset) { + spin_lock_irqsave(&dev->vbl_lock, irqflags); + dev->vblank_disable_allowed = true; ++ drm_reset_vblank_timestamp(dev, pipe); + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + + if (vblank->inmodeset & 0x2) diff --git a/queue-4.4/drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch b/queue-4.4/drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch new file mode 100644 index 00000000000..ddac3fc085e --- /dev/null +++ b/queue-4.4/drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch @@ -0,0 +1,65 @@ +From bb74fc1bf3072bd3ab4ed5f43afd287a63baf2d7 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Fri, 12 Feb 2016 20:30:30 +0100 +Subject: drm: Fix treatment of drm_vblank_offdelay in drm_vblank_on() (v2) + +From: Mario Kleiner + +commit bb74fc1bf3072bd3ab4ed5f43afd287a63baf2d7 upstream. + +drm_vblank_offdelay can have three different types of values: + +< 0 is to be always treated the same as dev->vblank_disable_immediate += 0 is to be treated as "never disable vblanks" +> 0 is to be treated as disable immediate if kms driver wants it + that way via dev->vblank_disable_immediate. Otherwise it is + a disable timeout in msecs. + +This got broken in Linux 3.18+ for the implementation of +drm_vblank_on. If the user specified a value of zero which should +always reenable vblank irqs in this function, a kms driver could +override the users choice by setting vblank_disable_immediate +to true. This patch fixes the regression and keeps the user in +control. + +v2: Only reenable vblank if there are clients left or the user + requested to "never disable vblanks" via offdelay 0. Enabling + vblanks even in the "delayed disable" case (offdelay > 0) was + specifically added by Ville in commit cd19e52aee922 + ("drm: Kick start vblank interrupts at drm_vblank_on()"), + but after discussion it turns out that this was done by accident. + + Citing Ville: "I think it just ended up as a mess due to changing + some of the semantics of offdelay<0 vs. offdelay==0 vs. + disable_immediate during the review of the series. So yeah, given + how drm_vblank_put() works now, I'd just make this check for + offdelay==0." + +Signed-off-by: Mario Kleiner +Reviewed-by: Daniel Vetter +Cc: michel@daenzer.net +Cc: vbabka@suse.cz +Cc: ville.syrjala@linux.intel.com +Cc: daniel.vetter@ffwll.ch +Cc: dri-devel@lists.freedesktop.org +Cc: alexander.deucher@amd.com +Cc: christian.koenig@amd.com +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_irq.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/gpu/drm/drm_irq.c ++++ b/drivers/gpu/drm/drm_irq.c +@@ -1494,8 +1494,7 @@ void drm_vblank_on(struct drm_device *de + * re-enable interrupts if there are users left, or the + * user wishes vblank interrupts to be enabled all the time. + */ +- if (atomic_read(&vblank->refcount) != 0 || +- (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0)) ++ if (atomic_read(&vblank->refcount) != 0 || drm_vblank_offdelay == 0) + WARN_ON(drm_vblank_enable(dev, pipe)); + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + } diff --git a/queue-4.4/drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch b/queue-4.4/drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch new file mode 100644 index 00000000000..2a8fd11aa7f --- /dev/null +++ b/queue-4.4/drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch @@ -0,0 +1,75 @@ +From e8235891b33799d597ff4ab5e45afe173a65da30 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Fri, 12 Feb 2016 20:30:27 +0100 +Subject: drm: No-Op redundant calls to drm_vblank_off() (v2) + +From: Mario Kleiner + +commit e8235891b33799d597ff4ab5e45afe173a65da30 upstream. + +Otherwise if a kms driver calls into drm_vblank_off() more than once +before calling drm_vblank_on() again, the redundant calls to +vblank_disable_and_save() will call drm_update_vblank_count() +while hw vblank counters and vblank timestamping are in a undefined +state during modesets, dpms off etc. + +At least with the legacy drm helpers it is not unusual to +get multiple calls to drm_vblank_off and drm_vblank_on, e.g., +half a dozen calls to drm_vblank_off and two calls to drm_vblank_on +were observed on radeon-kms during dpms-off -> dpms-on transition. + +We don't no-op calls from atomic modesetting drivers, as they +should do a proper job of tracking hw state. + +Fixes large jumps of the software maintained vblank counter due to +the hardware vblank counter resetting to zero during dpms off or +modeset, e.g., if radeon-kms is modified to use drm_vblank_off/on +instead of drm_vblank_pre/post_modeset(). + +This fixes a regression caused by the changes made to +drm_update_vblank_count() in Linux 4.4. + +v2: Don't no-op on atomic modesetting drivers, per suggestion + of Daniel Vetter. + +Signed-off-by: Mario Kleiner +Reviewed-by: Daniel Vetter +Cc: michel@daenzer.net +Cc: vbabka@suse.cz +Cc: ville.syrjala@linux.intel.com +Cc: alexander.deucher@amd.com +Cc: christian.koenig@amd.com +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_irq.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_irq.c ++++ b/drivers/gpu/drm/drm_irq.c +@@ -1313,7 +1313,13 @@ void drm_vblank_off(struct drm_device *d + spin_lock_irqsave(&dev->event_lock, irqflags); + + spin_lock(&dev->vbl_lock); +- vblank_disable_and_save(dev, pipe); ++ DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n", ++ pipe, vblank->enabled, vblank->inmodeset); ++ ++ /* Avoid redundant vblank disables without previous drm_vblank_on(). */ ++ if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset) ++ vblank_disable_and_save(dev, pipe); ++ + wake_up(&vblank->queue); + + /* +@@ -1415,6 +1421,9 @@ void drm_vblank_on(struct drm_device *de + return; + + spin_lock_irqsave(&dev->vbl_lock, irqflags); ++ DRM_DEBUG_VBL("crtc %d, vblank enabled %d, inmodeset %d\n", ++ pipe, vblank->enabled, vblank->inmodeset); ++ + /* Drop our private "prevent drm_vblank_get" refcount */ + if (vblank->inmodeset) { + atomic_dec(&vblank->refcount); diff --git a/queue-4.4/drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch b/queue-4.4/drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch new file mode 100644 index 00000000000..82bb0e6b96c --- /dev/null +++ b/queue-4.4/drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch @@ -0,0 +1,122 @@ +From 99b8e71597fadd6b2ac85e6e10f221f79dd9c1c1 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Fri, 12 Feb 2016 20:30:28 +0100 +Subject: drm: Prevent vblank counter bumps > 1 with active vblank clients. (v2) + +From: Mario Kleiner + +commit 99b8e71597fadd6b2ac85e6e10f221f79dd9c1c1 upstream. + +This fixes a regression introduced by the new drm_update_vblank_count() +implementation in Linux 4.4: + +Restrict the bump of the software vblank counter in drm_update_vblank_count() +to a safe maximum value of +1 whenever there is the possibility that +concurrent readers of vblank timestamps could be active at the moment, +as the current implementation of the timestamp caching and updating is +not safe against concurrent readers for calls to store_vblank() with a +bump of anything but +1. A bump != 1 would very likely return corrupted +timestamps to userspace, because the same slot in the cache could +be concurrently written by store_vblank() and read by one of those +readers in a non-atomic fashion and without the read-retry logic +detecting this collision. + +Concurrent readers can exist while drm_update_vblank_count() is called +from the drm_vblank_off() or drm_vblank_on() functions or other non-vblank- +irq callers. However, all those calls are happening with the vbl_lock +locked thereby preventing a drm_vblank_get(), so the vblank refcount +can't increase while drm_update_vblank_count() is executing. Therefore +a zero vblank refcount during execution of that function signals that +is safe for arbitrary counter bumps if called from outside vblank irq, +whereas a non-zero count is not safe. + +Whenever the function is called from vblank irq, we have to assume concurrent +readers could show up any time during its execution, even if the refcount +is currently zero, as vblank irqs are usually only enabled due to the +presence of readers, and because when it is called from vblank irq it +can't hold the vbl_lock to protect it from sudden bumps in vblank refcount. +Therefore also restrict bumps to +1 when the function is called from vblank +irq. + +Such bumps of more than +1 can happen at other times than reenabling +vblank irqs, e.g., when regular vblank interrupts get delayed by more +than 1 frame due to long held locks, long irq off periods, realtime +preemption on RT kernels, or system management interrupts. + +A better solution would be to rewrite the timestamp caching to use +full seqlocks to allow concurrent writes and reads for arbitrary +vblank counter increments. + +v2: Add code comment that this is essentially a hack and should + be replaced by a full seqlock implementation for caching of + timestamps. + +Signed-off-by: Mario Kleiner +Reviewed-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +Cc: michel@daenzer.net +Cc: vbabka@suse.cz +Cc: ville.syrjala@linux.intel.com +Cc: daniel.vetter@ffwll.ch +Cc: dri-devel@lists.freedesktop.org +Cc: alexander.deucher@amd.com +Cc: christian.koenig@amd.com +Signed-off-by: Dave Airlie + +--- + drivers/gpu/drm/drm_irq.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +--- a/drivers/gpu/drm/drm_irq.c ++++ b/drivers/gpu/drm/drm_irq.c +@@ -221,6 +221,49 @@ static void drm_update_vblank_count(stru + diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; + } + ++ /* ++ * FIMXE: Need to replace this hack with proper seqlocks. ++ * ++ * Restrict the bump of the software vblank counter to a safe maximum ++ * value of +1 whenever there is the possibility that concurrent readers ++ * of vblank timestamps could be active at the moment, as the current ++ * implementation of the timestamp caching and updating is not safe ++ * against concurrent readers for calls to store_vblank() with a bump ++ * of anything but +1. A bump != 1 would very likely return corrupted ++ * timestamps to userspace, because the same slot in the cache could ++ * be concurrently written by store_vblank() and read by one of those ++ * readers without the read-retry logic detecting the collision. ++ * ++ * Concurrent readers can exist when we are called from the ++ * drm_vblank_off() or drm_vblank_on() functions and other non-vblank- ++ * irq callers. However, all those calls to us are happening with the ++ * vbl_lock locked to prevent drm_vblank_get(), so the vblank refcount ++ * can't increase while we are executing. Therefore a zero refcount at ++ * this point is safe for arbitrary counter bumps if we are called ++ * outside vblank irq, a non-zero count is not 100% safe. Unfortunately ++ * we must also accept a refcount of 1, as whenever we are called from ++ * drm_vblank_get() -> drm_vblank_enable() the refcount will be 1 and ++ * we must let that one pass through in order to not lose vblank counts ++ * during vblank irq off - which would completely defeat the whole ++ * point of this routine. ++ * ++ * Whenever we are called from vblank irq, we have to assume concurrent ++ * readers exist or can show up any time during our execution, even if ++ * the refcount is currently zero, as vblank irqs are usually only ++ * enabled due to the presence of readers, and because when we are called ++ * from vblank irq we can't hold the vbl_lock to protect us from sudden ++ * bumps in vblank refcount. Therefore also restrict bumps to +1 when ++ * called from vblank irq. ++ */ ++ if ((diff > 1) && (atomic_read(&vblank->refcount) > 1 || ++ (flags & DRM_CALLED_FROM_VBLIRQ))) { ++ DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u " ++ "refcount %u, vblirq %u\n", pipe, diff, ++ atomic_read(&vblank->refcount), ++ (flags & DRM_CALLED_FROM_VBLIRQ) != 0); ++ diff = 1; ++ } ++ + DRM_DEBUG_VBL("updating vblank count on crtc %u:" + " current=%u, diff=%u, hw=%u hw_last=%u\n", + pipe, vblank->count, diff, cur_vblank, vblank->last); diff --git a/queue-4.4/drm-qxl-use-kmalloc_array-to-alloc-reloc_info-in-qxl_process_single_command.patch b/queue-4.4/drm-qxl-use-kmalloc_array-to-alloc-reloc_info-in-qxl_process_single_command.patch new file mode 100644 index 00000000000..2c56d14e781 --- /dev/null +++ b/queue-4.4/drm-qxl-use-kmalloc_array-to-alloc-reloc_info-in-qxl_process_single_command.patch @@ -0,0 +1,34 @@ +From 34855706c30d52b0a744da44348b5d1cc39fbe51 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 16 Feb 2016 14:25:00 +0100 +Subject: drm/qxl: use kmalloc_array to alloc reloc_info in qxl_process_single_command + +From: Gerd Hoffmann + +commit 34855706c30d52b0a744da44348b5d1cc39fbe51 upstream. + +This avoids integer overflows on 32bit machines when calculating +reloc_info size, as reported by Alan Cox. + +Cc: gnomes@lxorguk.ukuu.org.uk +Signed-off-by: Gerd Hoffmann +Reviewed-by: Daniel Vetter +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/qxl/qxl_ioctl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/qxl/qxl_ioctl.c ++++ b/drivers/gpu/drm/qxl/qxl_ioctl.c +@@ -168,7 +168,8 @@ static int qxl_process_single_command(st + cmd->command_size)) + return -EFAULT; + +- reloc_info = kmalloc(sizeof(struct qxl_reloc_info) * cmd->relocs_num, GFP_KERNEL); ++ reloc_info = kmalloc_array(cmd->relocs_num, ++ sizeof(struct qxl_reloc_info), GFP_KERNEL); + if (!reloc_info) + return -ENOMEM; + diff --git a/queue-4.4/drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch b/queue-4.4/drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch new file mode 100644 index 00000000000..3a5729e9628 --- /dev/null +++ b/queue-4.4/drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch @@ -0,0 +1,109 @@ +From 2b8341b3f917c108b47f6a8a771a40d226c57883 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Fri, 19 Feb 2016 02:06:38 +0100 +Subject: drm/radeon: Don't hang in radeon_flip_work_func on disabled crtc. (v2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mario Kleiner + +commit 2b8341b3f917c108b47f6a8a771a40d226c57883 upstream. + +This fixes a regression introduced in Linux 4.4. + +Limit the amount of time radeon_flip_work_func can +delay programming a page flip, by both limiting the +maximum amount of time per wait cycle and the maximum +number of wait cycles. Continue the flip if the limit +is exceeded, even if that may result in a visual or +timing glitch. + +This is to prevent a hang of page flips, as reported +in fdo bug #93746: Disconnecting a DisplayPort display +in parallel to a kms pageflip getting queued can cause +the following hang of page flips and thereby an unusable +desktop: + +1. kms pageflip ioctl() queues pageflip -> queues execution + of radeon_flip_work_func. + +2. Hotunplug of display causes the driver to DPMS OFF + the unplugged display. Display engine shuts down, + scanout no longer moves, but stays at its resting + position at start line of vblank. + +3. radeon_flip_work_func executes while crtc is off, and + due to the non-moving scanout position, the new flip + delay code introduced into Linux 4.4 by + commit 5b5561b3660d ("drm/radeon: Fixup hw vblank counter/ts..") + enters an infinite wait loop. + +4. After reconnecting the display, the pageflip continues + to hang in 3. and the display doesn't update its view + of the desktop. + +This patch fixes the Linux 4.4 regression from fdo bug #93746 + + + +v2: Skip wait immediately if !radeon_crtc->enabled, as + suggested by Michel. + +Reported-by: Bernd Steinhauser +Signed-off-by: Mario Kleiner +Tested-by: Bernd Steinhauser +Cc: Michel Dänzer +Cc: Alex Deucher +Reviewed-by: Michel Dänzer +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_display.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -403,7 +403,8 @@ static void radeon_flip_work_func(struct + struct drm_crtc *crtc = &radeon_crtc->base; + unsigned long flags; + int r; +- int vpos, hpos, stat, min_udelay; ++ int vpos, hpos, stat, min_udelay = 0; ++ unsigned repcnt = 4; + struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; + + down_read(&rdev->exclusive_lock); +@@ -454,7 +455,7 @@ static void radeon_flip_work_func(struct + * In practice this won't execute very often unless on very fast + * machines because the time window for this to happen is very small. + */ +- for (;;) { ++ while (radeon_crtc->enabled && repcnt--) { + /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank + * start in hpos, and to the "fudged earlier" vblank start in + * vpos. +@@ -472,10 +473,22 @@ static void radeon_flip_work_func(struct + /* Sleep at least until estimated real start of hw vblank */ + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); ++ if (min_udelay > vblank->framedur_ns / 2000) { ++ /* Don't wait ridiculously long - something is wrong */ ++ repcnt = 0; ++ break; ++ } + usleep_range(min_udelay, 2 * min_udelay); + spin_lock_irqsave(&crtc->dev->event_lock, flags); + }; + ++ if (!repcnt) ++ DRM_DEBUG_DRIVER("Delay problem on crtc %d: min_udelay %d, " ++ "framedur %d, linedur %d, stat %d, vpos %d, " ++ "hpos %d\n", work->crtc_id, min_udelay, ++ vblank->framedur_ns / 1000, ++ vblank->linedur_ns / 1000, stat, vpos, hpos); ++ + /* do the flip (mmio) */ + radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); + diff --git a/queue-4.4/drm-radeon-pm-adjust-display-configuration-after-powerstate.patch b/queue-4.4/drm-radeon-pm-adjust-display-configuration-after-powerstate.patch new file mode 100644 index 00000000000..db96a25c89b --- /dev/null +++ b/queue-4.4/drm-radeon-pm-adjust-display-configuration-after-powerstate.patch @@ -0,0 +1,49 @@ +From 39d4275058baf53e89203407bf3841ff2c74fa32 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 19 Feb 2016 18:05:10 -0500 +Subject: drm/radeon/pm: adjust display configuration after powerstate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alex Deucher + +commit 39d4275058baf53e89203407bf3841ff2c74fa32 upstream. + +set_power_state defaults to no displays, so we need to update +the display configuration after setting up the powerstate on the +first call. In most cases this is not an issue since ends up +getting called multiple times at any given modeset and the proper +order is achieved in the display changed handling at the top of +the function. + +Reviewed-by: Christian König +Acked-by: Jordan Lazare +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_pm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -1075,8 +1075,6 @@ force: + + /* update display watermarks based on new power state */ + radeon_bandwidth_update(rdev); +- /* update displays */ +- radeon_dpm_display_configuration_changed(rdev); + + rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; + rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; +@@ -1097,6 +1095,9 @@ force: + + radeon_dpm_post_set_power_state(rdev); + ++ /* update displays */ ++ radeon_dpm_display_configuration_changed(rdev); ++ + if (rdev->asic->dpm.force_performance_level) { + if (rdev->pm.dpm.thermal_active) { + enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; diff --git a/queue-4.4/drm-radeon-use-post-decrement-in-error-handling.patch b/queue-4.4/drm-radeon-use-post-decrement-in-error-handling.patch new file mode 100644 index 00000000000..835fda6a61d --- /dev/null +++ b/queue-4.4/drm-radeon-use-post-decrement-in-error-handling.patch @@ -0,0 +1,36 @@ +From bc3f5d8c4ca01555820617eb3b6c0857e4df710d Mon Sep 17 00:00:00 2001 +From: Rasmus Villemoes +Date: Mon, 15 Feb 2016 19:41:47 +0100 +Subject: drm/radeon: use post-decrement in error handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rasmus Villemoes + +commit bc3f5d8c4ca01555820617eb3b6c0857e4df710d upstream. + +We need to use post-decrement to get the pci_map_page undone also for +i==0, and to avoid some very unpleasant behaviour if pci_map_page +failed already at i==0. + +Reviewed-by: Christian König +Signed-off-by: Rasmus Villemoes +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -758,7 +758,7 @@ static int radeon_ttm_tt_populate(struct + 0, PAGE_SIZE, + PCI_DMA_BIDIRECTIONAL); + if (pci_dma_mapping_error(rdev->pdev, gtt->ttm.dma_address[i])) { +- while (--i) { ++ while (i--) { + pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i], + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + gtt->ttm.dma_address[i] = 0; diff --git a/queue-4.4/make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch b/queue-4.4/make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch new file mode 100644 index 00000000000..bc3e749b8e7 --- /dev/null +++ b/queue-4.4/make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch @@ -0,0 +1,67 @@ +From 3ed47db34f480df7caf44436e3e63e555351ae9a Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 22 Jan 2016 18:08:52 -0500 +Subject: make sure that freeing shmem fast symlinks is RCU-delayed + +From: Al Viro + +commit 3ed47db34f480df7caf44436e3e63e555351ae9a upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/shmem_fs.h | 5 +---- + mm/shmem.c | 9 ++++----- + 2 files changed, 5 insertions(+), 9 deletions(-) + +--- a/include/linux/shmem_fs.h ++++ b/include/linux/shmem_fs.h +@@ -15,10 +15,7 @@ struct shmem_inode_info { + unsigned int seals; /* shmem seals */ + unsigned long flags; + unsigned long alloced; /* data pages alloced to file */ +- union { +- unsigned long swapped; /* subtotal assigned to swap */ +- char *symlink; /* unswappable short symlink */ +- }; ++ unsigned long swapped; /* subtotal assigned to swap */ + struct shared_policy policy; /* NUMA memory alloc policy */ + struct list_head swaplist; /* chain of maybes on swap */ + struct simple_xattrs xattrs; /* list of xattrs */ +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -620,8 +620,7 @@ static void shmem_evict_inode(struct ino + list_del_init(&info->swaplist); + mutex_unlock(&shmem_swaplist_mutex); + } +- } else +- kfree(info->symlink); ++ } + + simple_xattrs_free(&info->xattrs); + WARN_ON(inode->i_blocks); +@@ -2462,13 +2461,12 @@ static int shmem_symlink(struct inode *d + info = SHMEM_I(inode); + inode->i_size = len-1; + if (len <= SHORT_SYMLINK_LEN) { +- info->symlink = kmemdup(symname, len, GFP_KERNEL); +- if (!info->symlink) { ++ inode->i_link = kmemdup(symname, len, GFP_KERNEL); ++ if (!inode->i_link) { + iput(inode); + return -ENOMEM; + } + inode->i_op = &shmem_short_symlink_operations; +- inode->i_link = info->symlink; + } else { + error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); + if (error) { +@@ -3083,6 +3081,7 @@ static struct inode *shmem_alloc_inode(s + static void shmem_destroy_callback(struct rcu_head *head) + { + struct inode *inode = container_of(head, struct inode, i_rcu); ++ kfree(inode->i_link); + kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); + } + diff --git a/queue-4.4/series b/queue-4.4/series index 86eca8ea7e9..e2db8553ac6 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -224,3 +224,12 @@ drm-i915-skl-don-t-skip-mst-encoders-in-skl_ddi_pll_select.patch drm-i915-dsi-defend-gpio-table-against-out-of-bounds-access.patch drm-i915-dsi-don-t-pass-arbitrary-data-to-sideband.patch drm-i915-fix-error-path-in-intel_setup_gmbus.patch +drm-qxl-use-kmalloc_array-to-alloc-reloc_info-in-qxl_process_single_command.patch +drm-radeon-use-post-decrement-in-error-handling.patch +drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch +drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch +drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch +drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch +drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch +drm-radeon-pm-adjust-display-configuration-after-powerstate.patch +make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch -- 2.47.3