> From: Gerald Hanuer <[email protected]>
> Date: Mon, 28 Sep 2015 03:36:54 +0000
> 
>  Hello bugs@,
> 
>  >>Waking from wscons display.vblank hardlocks system.
> 
>   I was able to get a trace out of  ( kern.splassert=2  )
> 
>   Not able to  get to ddb.
> 
>   Full sendbug(1) output is with my first mail
> 
>   The kernel dmesg(8) that made this trace follows.
> 
>    The source was checkout at Sun Sep 27 22:35:00.
> 
>  /bsd: splassert: assertwaitok: want 0 have 4
>  /bsd: Starting stack trace...
>  /bsd: assertwaitok() at assertwaitok+0x20
>  /bsd: mi_switch() at mi_switch+0x45
>  /bsd: sleep_finish() at sleep_finish+0xb1
>  /bsd: ironlake_edp_panel_on() at ironlake_edp_panel_on+0x716
>  /bsd: ironlake_edp_panel_on() at ironlake_edp_panel_on+0xab8
>  /bsd: intel_dp_stop_link_train() at intel_dp_stop_link_train+0x8c
>  /bsd: intel_ddi_enable_transcoder_func() at
> intel_ddi_enable_transcoder_func+0x554
>  /bsd: hsw_enable_ips() at hsw_enable_ips+0x1e68
>  /bsd: intel_connector_dpms() at intel_connector_dpms+0x5d
>  /bsd: drm_fb_helper_dpms() at drm_fb_helper_dpms+0xba
>  /bsd: wsdisplay_burner() at wsdisplay_burner+0x2d
>  /bsd: softclock() at softclock+0x315
>  /bsd: softintr_dispatch() at softintr_dispatch+0x8b
>  /bsd: Xsoftclock() at Xsoftclock+0x1f
>  /bsd: --- interrupt ---

Ah, that's not good.  So the code that turns the display back on
sleeps now.  Does the diff below fix the problem?

Index: i915_drv.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v
retrieving revision 1.92
diff -u -p -r1.92 i915_drv.c
--- i915_drv.c  28 Sep 2015 06:47:23 -0000      1.92
+++ i915_drv.c  28 Sep 2015 08:26:06 -0000
@@ -966,6 +966,7 @@ int inteldrm_load_font(void *, void *, s
 int inteldrm_list_font(void *, struct wsdisplay_font *);
 int inteldrm_getchar(void *, int, int, struct wsdisplay_charcell *);
 void inteldrm_burner(void *, u_int, u_int);
+void inteldrm_burner_cb(void *);
 
 struct wsscreen_descr inteldrm_stdscreen = {
        "std",
@@ -1140,19 +1141,32 @@ void
 inteldrm_burner(void *v, u_int on, u_int flags)
 {
        struct inteldrm_softc *dev_priv = v;
-       struct drm_fb_helper *helper = &dev_priv->fbdev->helper;
-       int dpms_mode;
+
+       task_del(systq, &dev_priv->burner_task);
 
        if (on)
-               dpms_mode = DRM_MODE_DPMS_ON;
+               dev_priv->burner_dpms_mode = DRM_MODE_DPMS_ON;
        else {
                if (flags & WSDISPLAY_BURN_VBLANK)
-                       dpms_mode = DRM_MODE_DPMS_OFF;
+                       dev_priv->burner_dpms_mode = DRM_MODE_DPMS_OFF;
                else
-                       dpms_mode = DRM_MODE_DPMS_STANDBY;
+                       dev_priv->burner_dpms_mode = DRM_MODE_DPMS_STANDBY;
        }
 
-       drm_fb_helper_dpms(helper, dpms_mode);
+       /*
+        * Setting the DPMS mode may sleep while waiting for the display
+        * to come back on so hand things off to a taskq.
+        */
+       task_add(systq, &dev_priv->burner_task);
+}
+
+void
+inteldrm_burner_cb(void *arg1)
+{
+       struct inteldrm_softc *dev_priv = arg1;
+       struct drm_fb_helper *helper = &dev_priv->fbdev->helper;
+
+       drm_fb_helper_dpms(helper, dev_priv->burner_dpms_mode);
 }
 
 int
@@ -1448,6 +1462,7 @@ inteldrm_attach(struct device *parent, s
        rasops_init(ri, 160, 160);
 
        task_set(&dev_priv->switchtask, inteldrm_doswitch, dev_priv);
+       task_set(&dev_priv->burner_task, inteldrm_burner_cb, dev_priv);
 
        inteldrm_stdscreen.capabilities = ri->ri_caps;
        inteldrm_stdscreen.nrows = ri->ri_rows;
Index: i915_drv.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.h,v
retrieving revision 1.68
diff -u -p -r1.68 i915_drv.h
--- i915_drv.h  26 Sep 2015 11:17:15 -0000      1.68
+++ i915_drv.h  28 Sep 2015 08:26:06 -0000
@@ -1466,6 +1466,9 @@ typedef struct inteldrm_softc {
        struct task switchtask;
        struct rasops_info ro;
 
+       struct task burner_task;
+       int burner_dpms_mode;
+
        struct backlight_device {
                struct intel_connector *connector;
                struct {

Reply via email to