xf86-video-intel: 3 commits - src/backlight.c src/backlight.h src/intel_device.c src/intel_driver.h src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Wed Jul 23 14:06:12 PDT 2014


 src/backlight.c       |   23 ++++++++++++++++++-----
 src/backlight.h       |    3 ++-
 src/intel_device.c    |   11 +++++++++++
 src/intel_driver.h    |    1 +
 src/sna/kgem.c        |   21 ++++++++++++++-------
 src/sna/kgem.h        |    3 ++-
 src/sna/sna.h         |    2 ++
 src/sna/sna_accel.c   |   26 ++++++++++++++++++++++++++
 src/sna/sna_display.c |    5 +++--
 src/sna/sna_driver.c  |   12 ++++++++++--
 10 files changed, 89 insertions(+), 18 deletions(-)

New commits:
commit 5935c93ce77a5da09aab9b45b1a5710d681c171e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 23 21:59:20 2014 +0100

    sna: Keep the backlight at the same brightness when switching away
    
    Before VT switching, we disable all the outputs. This has the
    side-effect of disabling the backlight, but commonly the console does
    not set the backlight brightness itself and so we re-enable the
    backlight on its behalf. Rather than set the backlight to max
    brightness, reset it to the last user value, as maximum can be very
    bright!
    
    Reported-by: Mark Kettenis <mark.kettenis at xs4all.nl
    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 376f261..26f35ec 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -6090,7 +6090,7 @@ void sna_mode_reset(struct sna *sna)
 		rotation_reset(&sna_crtc->sprite);
 	}
 
-	/* VT switching, likely to fbcon so make the backlight usable */
+	/* VT switching, likely to be fbcon so make the backlight usable */
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		struct sna_output *sna_output = to_sna_output(config->output[i]);
 
@@ -6101,7 +6101,7 @@ void sna_mode_reset(struct sna *sna)
 			continue;
 
 		sna_output_backlight_set(sna_output,
-					 sna_output->backlight.max);
+					 sna_output->backlight_active_level);
 	}
 
 	/* drain the event queue */
commit f9e7ac7db7b0331131aa1df3a90d4b2692949efa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 23 21:53:31 2014 +0100

    backlight: Set structure to safe values when not initialised
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/backlight.c b/src/backlight.c
index f0c549e..72e6bfe 100644
--- a/src/backlight.c
+++ b/src/backlight.c
@@ -74,6 +74,15 @@
  * If only things were as simple as on OpenBSD! :)
  */
 
+void backlight_init(struct backlight *b)
+{
+	b->type = BL_NONE;
+	b->iface = NULL;
+	b->fd = -1;
+	b->pid = -1;
+	b->max = -1;
+}
+
 #ifdef __OpenBSD__
 
 #include <dev/wscons/wsconsio.h>
@@ -384,23 +393,27 @@ int backlight_open(struct backlight *b, char *iface)
 	if (iface == NULL)
 		iface = __backlight_find();
 	if (iface == NULL)
-		return -1;
+		goto err;
 
 	b->type = __backlight_type(iface);
 
 	b->max = __backlight_read(iface, "max_brightness");
 	if (b->max <= 0)
-		return -1;
+		goto err;
 
 	level = __backlight_read(iface, "brightness");
-	if (level < 0)
-		return -1;
+	if (level)
+		goto err;
 
 	if (!__backlight_direct_init(b, iface) &&
 	    !__backlight_helper_init(b, iface))
-		return -1;
+		goto err;
 
 	return level;
+
+err:
+	backlight_init(b);
+	return -1;
 }
 
 int backlight_set(struct backlight *b, int level)
diff --git a/src/backlight.h b/src/backlight.h
index c251bd9..6391be7 100644
--- a/src/backlight.h
+++ b/src/backlight.h
@@ -38,12 +38,13 @@ enum backlight_type {
 struct backlight {
 	char *iface;
 	enum backlight_type type;
-	int max;
+	int original, max;
 	int pid, fd;
 };
 
 enum backlight_type backlight_exists(const char *iface);
 
+void backlight_init(struct backlight *backlight);
 int backlight_open(struct backlight *backlight, char *iface);
 int backlight_set(struct backlight *backlight, int level);
 int backlight_get(struct backlight *backlight);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index ffb8bb9..376f261 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3683,6 +3683,7 @@ reset:
 	output->driver_private = sna_output;
 	sna_output->base = output;
 
+	backlight_init(&sna_output->backlight);
 	if (sna_output->is_panel)
 		sna_output_backlight_init(output);
 
commit bc50dff844b97e655483c9eaf0effeec6a9ab4dd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 23 21:43:02 2014 +0100

    sna: Disable rendering with the DRM device whilst away from VT
    
    As root, X gets away with many things, including submitting commands to
    the DRM device whilst it is no longer authorised (i.e. when it has
    relinquished master to another client across a VT switch). In the
    non-root future, if we attempt to use the device whilst unauthorized the
    rendering will be lost and we will mark the device as unusable. So flush
    our render queue to the device around a VT switch.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_device.c b/src/intel_device.c
index 22eedb6..8be38c1 100644
--- a/src/intel_device.c
+++ b/src/intel_device.c
@@ -528,6 +528,17 @@ int __intel_peek_fd(ScrnInfoPtr scrn)
 	return dev->fd;
 }
 
+int intel_has_render_node(ScrnInfoPtr scrn)
+{
+	struct intel_device *dev;
+	struct stat st;
+
+	dev = intel_device(scrn);
+	assert(dev && dev->fd != -1);
+
+	return is_render_node(dev->fd, &st);
+}
+
 int intel_get_device(ScrnInfoPtr scrn)
 {
 	struct intel_device *dev;
diff --git a/src/intel_driver.h b/src/intel_driver.h
index d295250..4f6a764 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -126,6 +126,7 @@ int intel_open_device(int entity_num,
 		      const struct pci_device *pci,
 		      struct xf86_platform_device *dev);
 int __intel_peek_fd(ScrnInfoPtr scrn);
+int intel_has_render_node(ScrnInfoPtr scrn);
 int intel_get_device(ScrnInfoPtr scrn);
 const char *intel_get_client_name(ScrnInfoPtr scrn);
 int intel_get_client_fd(ScrnInfoPtr scrn);
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index e5d2d14..628fa3c 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3378,7 +3378,7 @@ void _kgem_submit(struct kgem *kgem)
 	assert(kgem->next_request != NULL);
 }
 
-static void find_hang_state(struct kgem *kgem, char *path, int maxlen)
+static bool find_hang_state(struct kgem *kgem, char *path, int maxlen)
 {
 	int minor = kgem_get_minor(kgem);
 
@@ -3389,16 +3389,17 @@ static void find_hang_state(struct kgem *kgem, char *path, int maxlen)
 
 	snprintf(path, maxlen, "/sys/class/drm/card%d/error", minor);
 	if (access(path, R_OK) == 0)
-		return;
+		return true;
 
 	snprintf(path, maxlen, "/sys/kernel/debug/dri/%d/i915_error_state", minor);
 	if (access(path, R_OK) == 0)
-		return;
+		return true;
 
 	snprintf(path, maxlen, "/debug/dri/%d/i915_error_state", minor);
 	if (access(path, R_OK) == 0)
-		return;
+		return true;
 
+	return false;
 	path[0] = '\0';
 }
 
@@ -3409,21 +3410,27 @@ void kgem_throttle(struct kgem *kgem)
 
 	kgem->wedged = __kgem_throttle(kgem, true);
 	if (kgem->wedged) {
+		static int once;
 		char path[128];
 
-		find_hang_state(kgem, path, sizeof(path));
-
 		xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
 			   "Detected a hung GPU, disabling acceleration.\n");
-		if (*path != '\0')
+		if (!once && find_hang_state(kgem, path, sizeof(path))) {
 			xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR,
 				   "When reporting this, please include %s and the full dmesg.\n",
 				   path);
+			once = 1;
+		}
 
 		kgem->need_throttle = false;
 	}
 }
 
+int kgem_is_wedged(struct kgem *kgem)
+{
+	return __kgem_throttle(kgem, true);
+}
+
 static void kgem_purge_cache(struct kgem *kgem)
 {
 	struct kgem_bo *bo, *next;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index be9b7e8..8cf596c 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -121,7 +121,7 @@ enum {
 
 struct kgem {
 	int fd;
-	int wedged;
+	unsigned wedged;
 	unsigned gen;
 
 	uint32_t unique_id;
@@ -761,6 +761,7 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
 bool kgem_buffer_is_inplace(struct kgem_bo *bo);
 void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
 
+int kgem_is_wedged(struct kgem *kgem);
 void kgem_throttle(struct kgem *kgem);
 #define MAX_INACTIVE_TIME 10
 bool kgem_expire_cache(struct kgem *kgem);
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 281418b..206ecc9 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -995,6 +995,8 @@ void sna_accel_block_handler(struct sna *sna, struct timeval **tv);
 void sna_accel_wakeup_handler(struct sna *sna);
 void sna_accel_watch_flush(struct sna *sna, int enable);
 void sna_accel_flush(struct sna *sna);
+void sna_accel_enter(struct sna *sna);
+void sna_accel_leave(struct sna *sna);
 void sna_accel_close(struct sna *sna);
 void sna_accel_free(struct sna *sna);
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 222c8b5..e4d6f82 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -17790,6 +17790,32 @@ void sna_accel_watch_flush(struct sna *sna, int enable)
 	sna->watch_flush += enable;
 }
 
+void sna_accel_leave(struct sna *sna)
+{
+	DBG(("%s\n", __FUNCTION__));
+
+	/* as root we always have permission to render */
+	if (geteuid() == 0)
+		return;
+
+	/* as a user, we can only render now if we have a rendernode */
+	if (intel_has_render_node(sna->scrn))
+		return;
+
+	/* no longer authorized to use our fd */
+	DBG(("%s: dropping render privileges\n", __FUNCTION__));
+
+	kgem_submit(&sna->kgem);
+	sna->kgem.wedged |= 2;
+}
+
+void sna_accel_enter(struct sna *sna)
+{
+	DBG(("%s\n", __FUNCTION__));
+	sna->kgem.wedged &= kgem_is_wedged(&sna->kgem);
+	kgem_throttle(&sna->kgem);
+}
+
 void sna_accel_close(struct sna *sna)
 {
 	DBG(("%s\n", __FUNCTION__));
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 7f4540d..5e54125 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -892,10 +892,12 @@ static void sna_uevent_fini(struct sna *sna) { }
 static void sna_leave_vt(VT_FUNC_ARGS_DECL)
 {
 	SCRN_INFO_PTR(arg);
+	struct sna *sna = to_sna(scrn);
 
 	DBG(("%s\n", __FUNCTION__));
 
-	sna_mode_reset(to_sna(scrn));
+	sna_accel_leave(sna);
+	sna_mode_reset(sna);
 
 	if (intel_put_master(scrn))
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1208,7 +1210,13 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
 		sna->flags &= ~SNA_REPROBE;
 	}
 
-	return sna_set_desired_mode(sna);
+	if (!sna_set_desired_mode(sna)) {
+		intel_put_master(scrn);
+		return FALSE;
+	}
+
+	sna_accel_enter(sna);
+	return TRUE;
 }
 
 static Bool sna_switch_mode(SWITCH_MODE_ARGS_DECL)


More information about the xorg-commit mailing list