Kernel warning when mode setting with no connectors connected

Russell King - ARM Linux linux at arm.linux.org.uk
Sat Apr 12 14:20:18 PDT 2014


On Sat, Apr 12, 2014 at 10:42:52PM +0200, Daniel Vetter wrote:
> On Sat, Apr 12, 2014 at 12:32 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> >
> > I've been seeing the following warning when a mode is attempted to be
> > set after boot when no display connectors are connected.  This typically
> > happens if your platform has just a HDMI output, and the TV connected
> > to the HDMI output is fully powered off.
> >
> > This has been happening for quite some time now... I should've probably
> > reported it earlier.  I've seen it both with imx-drm and armada-drm.
> >
> > WARNING: CPU: 0 PID: 846 at drivers/gpu/drm/drm_crtc.c:2074 drm_mode_set_config_internal+0xd0/0xd8()
> > Modules linked in: rfcomm bnep bluetooth 6lowpan_iphc brcmfmac brcmutil snd_soc_fsl_spdif imx_pcm_dma imx_sdma imx_thermal imx2_wdt snd_soc_imx_spdif nfsd exportfs
> > CPU: 0 PID: 846 Comm: Xorg Not tainted 3.14.0+ #1027
> > Backtrace:
> > [<c0011cf4>] (dump_backtrace) from [<c0011e94>] (show_stack+0x18/0x1c)
> >  r6:0000081a r5:00000009 r4:00000000 r3:00000000
> > [<c0011e7c>] (show_stack) from [<c066b4e8>] (dump_stack+0x74/0x90)
> > [<c066b474>] (dump_stack) from [<c0024588>] (warn_slowpath_common+0x70/0x90)
> >  r4:00000000 r3:c09344b8
> > [<c0024518>] (warn_slowpath_common) from [<c00245cc>] (warn_slowpath_null+0x24/0x2c)
> >  r8:ea3c3818 r7:00000001 r6:e9904500 r5:00000000 r4:ea3c3818
> > [<c00245a8>] (warn_slowpath_null) from [<c03474e4>] (drm_mode_set_config_internal+0xd0/0xd8)
> > [<c0347414>] (drm_mode_set_config_internal) from [<c03497c8>] (drm_mode_setcrtc+0x378/0x4b4)
> >  r6:ea3c3400 r5:e8d78b00 r4:e9981e48 r3:00000000
> > [<c0349450>] (drm_mode_setcrtc) from [<c033c9d0>] (drm_ioctl+0x3f4/0x498)
> >  r10:c06b8fa0 r9:e9981e48 r8:e9981e48 r7:e9980000 r6:e98260c0 r5:000000a2
> >  r4:ea3c3400
> > [<c033c5dc>] (drm_ioctl) from [<c01095b8>] (do_vfs_ioctl+0x80/0x5d4)
> >  r10:00000000 r9:e9980000 r8:00000006 r7:c06864a2 r6:be911850 r5:e9826900
> >  r4:ea3bf100
> > [<c0109538>] (do_vfs_ioctl) from [<c0109b4c>] (SyS_ioctl+0x40/0x5c)
> >  r9:e9980000 r8:00000006 r7:c06864a2 r6:be911850 r5:e9826900 r4:e9826900
> > [<c0109b0c>] (SyS_ioctl) from [<c000e6e0>] (ret_fast_syscall+0x0/0x30)
> >  r8:c000e864 r7:00000036 r6:00000006 r5:c06864a2 r4:be911850 r3:00000001
> > ---[ end trace 46155b08f61d1185 ]---
> >
> > In drm_mode_set_config_internal(), this check is done:
> >
> >         fb = set->fb;
> >
> >         ret = crtc->funcs->set_config(set);
> >         if (ret == 0) {
> >                 /* crtc->fb must be updated by ->set_config, enforces this. */
> >                 WARN_ON(fb != crtc->fb);
> >         }
> >
> > However, drm_crtc_helper_set_config() does this:
> >
> >         if (!set->mode)
> >                 set->fb = NULL;
> >
> >         if (set->fb) {
> > ...
> >         } else {
> >                 DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
> >                 return drm_crtc_helper_disable(set->crtc);
> >         }
> >
> > which results in a zero return with crtc->fb set to NULL, possibly
> > being different to what set->fb was originally.
> >
> > I haven't debugged this fully yet as the only side effect is the
> > warning.
> 
> This is strange - passing a NULL mode and a non-NULL fb to
> ->set_config is a bug, and in the i915 ->set_config callback
> (intel_crtc_set_config) we even have a BUG_ON to check for that. A few
> release ago the fb helper code violated this which wreak a bit of
> havoc in the i915 modeset code until I've fixed it, but now this
> really should hold everywhere.

That was just a guess.

drm_mode_set_config_internal: pre: fb   (null) mode   (null) crtc dae72418 crtc->fb   (null)
drm_crtc_helper_set_config: disable
drm_helper_disable_unused_functions: crtc dae72018 crtc->fb   (null)
drm_helper_disable_unused_functions: crtc dae72418 crtc->fb   (null)
drm_mode_set_config_internal: post: fb   (null) mode   (null) crtc->fb   (null) ret 0

drm_mode_set_config_internal: pre: fb dac09680 mode db6b1900 crtc dae72018 crtc->fb   (null)
drm_helper_disable_unused_functions: crtc dae72018 crtc->fb dac09680
drm_helper_disable_unused_functions: crtc dae72418 crtc->fb   (null)
drm_crtc_helper_set_config: success
drm_mode_set_config_internal: post: fb dac09680 mode db6b1900 crtc->fb   (null) ret 0
------------[ cut here ]------------
WARNING: CPU: 0 PID: 866 at drivers/gpu/drm/drm_crtc.c:2075 drm_mode_set_config_internal+0x11c/0x130()

'fb' is set->fb, 'mode' is set->mode.

So what happens is that a mode is attempted to be set with no connectors.
We get to the

	if (mode_changed) {

bit in drm_crtc_helper_set_config().  I haven't checked whether
drm_helper_crtc_in_use() returns true, I guess it doesn't.  We then
fall down to drm_helper_disable_unused_functions() which disables
the CRTC we're trying to set the mode for, setting crtc->fb to NULL.

We then return success, which results in the check for crtc->fb ==
set->fb, which fails.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.


More information about the dri-devel mailing list