> 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 {