Patch "drm/radeon: Don't hang in radeon_flip_work_func on disabled crtc. (v2)" has been added to the 4.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    drm/radeon: Don't hang in radeon_flip_work_func on disabled crtc. (v2)

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From 2b8341b3f917c108b47f6a8a771a40d226c57883 Mon Sep 17 00:00:00 2001
From: Mario Kleiner <mario.kleiner.de@xxxxxxxxx>
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 <mario.kleiner.de@xxxxxxxxx>

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

<https://bugs.freedesktop.org/show_bug.cgi?id=93746>

v2: Skip wait immediately if !radeon_crtc->enabled, as
    suggested by Michel.

Reported-by: Bernd Steinhauser <linux@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Mario Kleiner <mario.kleiner.de@xxxxxxxxx>
Tested-by: Bernd Steinhauser <linux@xxxxxxxxxxxxxxxxxxxx>
Cc: Michel Dänzer <michel.daenzer@xxxxxxx>
Cc: Alex Deucher <alexander.deucher@xxxxxxx>
Reviewed-by: Michel Dänzer <michel.daenzer@xxxxxxx>
Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
 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);
 


Patches currently in stable-queue which might be from mario.kleiner.de@xxxxxxxxx are

queue-4.4/drm-prevent-vblank-counter-bumps-1-with-active-vblank-clients.-v2.patch
queue-4.4/drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch
queue-4.4/drm-nouveau-display-enable-vblank-irqs-after-display-engine-is-on-again.patch
queue-4.4/drm-fix-drm_vblank_pre-post_modeset-regression-from-linux-4.4.patch
queue-4.4/drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch
queue-4.4/drm-no-op-redundant-calls-to-drm_vblank_off-v2.patch
queue-4.4/drm-amdgpu-don-t-hang-in-amdgpu_flip_work_func-on-disabled-crtc.patch

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]