xf86-video-intel: src/sna/sna_display.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Sep 29 00:50:24 PDT 2015


 src/sna/sna_display.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

New commits:
commit 679ee12079a7d2682d41506b81973c7c7d4fa1d8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 27 19:05:26 2015 +0100

    sna: Prevent infinite recursion on udevless RRGetInfo()
    
    As summarised by Mark Kettenis:
    
        Unfortunately commit 2c08d72393e4c8ddf5926571b087459aaa225cb1 that
        was made to resolve this bug introduced infinite recursion if
        polling udev for events fails (which is always the case on systems
        without udev).  The scenario is as follows:
    
        1. The server calls RRGetInfo().
        2. RRGetInfo() calls sna_randr_getinfo()
        3. sna_randr_getinfo() calls sna_uevent_poll(), which returns false
        4. sna_randr_getinfo() calls sna_mode_discover()
        5. sna_mode_discover() calls RRGetInfo()
    
        and we jump straight back to step 2, until we run out of stack
        space and crash
    
    Reported-by: Mark Kettenis <kettenis at openbsd.org>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91929#c8
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 1b1a125..6db379d 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4900,6 +4900,7 @@ void sna_mode_discover(struct sna *sna)
 				DBG(("%s: output %s (id=%d), changed state, reprobing\n",
 				     __FUNCTION__, output->name, sna_output->id));
 				sna_output->last_detect = 0;
+				changed |= 4;
 			}
 			continue;
 		}
@@ -4918,7 +4919,8 @@ void sna_mode_discover(struct sna *sna)
 		changed |= 2;
 	}
 
-	if (changed) {
+	/* Have the list of available outputs been updated? */
+	if (changed & 3) {
 		DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__));
 
 		sna_mode_set_primary(sna);
@@ -4933,8 +4935,12 @@ void sna_mode_discover(struct sna *sna)
 		xf86RandR12TellChanged(screen);
 	}
 
-	RRGetInfo(screen, TRUE);
-	RRTellChanged(screen);
+	/* If anything has changed, refresh the RandR information.
+	 * Note this could recurse once from udevless RRGetInfo() probes,
+	 * but only once.
+	 */
+	if (changed)
+		RRGetInfo(screen, TRUE);
 }
 
 /* Since we only probe the current mode on startup, we may not have the full


More information about the xorg-commit mailing list