Re: drm: Bogus WARN() in drm_atomic_helper_update_legacy_modeset_state() ?

Thierry Reding
2015-11-12T16:28:08Z

[-- Attachment #1: Type: text/plain, Size: 4622 bytes --]

On Thu, Nov 12, 2015 at 01:57:11PM +0000, Liviu Dudau wrote:
> On Thu, Nov 12, 2015 at 01:16:55PM +0100, Thierry Reding wrote:
> > On Wed, Nov 11, 2015 at 04:09:42PM +0000, Liviu Dudau wrote:
> > > On Tue, Nov 10, 2015 at 05:56:15PM +0100, Thierry Reding wrote:
> > > > On Tue, Nov 10, 2015 at 03:01:03PM +0000, Liviu Dudau wrote:
> > > > > Hello,
> > > > >
> > > > > When booting my Juno board with the HDLCD driver that I have converted to
> > > > > atomic operations I'm getting the following warning:
> > > >
> > > > Perhaps you can provide pointers to the source code, that might make it
> > > > easier for people to spot what's going wrong.
> > > >
> > > > Thierry
> > >
> > > Hi Thierry,
> > >
> > > I have just pushed to the mailing lists my patch series. [1] [2]
> > >
> > > If you want to checkout the code I also have a branch here:
> > >
> > > git://git://linux-arm.org/linux-ld testing/hdlcd
> >
> > Okay, so if I understand correctly you're using the tda998x as encoder/
> > connector attached to your new HDLCD driver. I think the problem isn't
> > so much that nothing has set up the CRTC for the encoder, but rather
> > that the tda998x encoder tries to statically associate the encoder with
> > the connector. While that might be correct in that it represents the
> > hardware state (i.e. there is no way to physically route it anywhere
> > else), the DRM logical state is that it's not connected until a complete
> > pipeline has been set up, in which case a CRTC would have been assigned
> > to the encoder.
> >
> > If your setup were working correctly you'd never reach the WARN_ON
> > because the
> >
> > if (connector->encoder) {
> >
> > conditional (on line 673 in drivers/gpu/drm/drm_atomic_helper.c) would
> > have evaluated to false already, since logically there'd be no encoder
> > associated with the connector yet.
>
> Your analysis is spot on and matches my conditions. However ...
>
> >
> > Does the patch below help? Let me know and I can produce a proper patch.
> >
> > Thierry
> >
> > --- >8 ---
> > diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
> > index 896b6aaf8c4d..8b0a402190eb 100644
> > --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> > +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> > @@ -1453,7 +1453,6 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
> > if (ret)
> > goto err_sysfs;
> >
> > - priv->connector.encoder = &priv->encoder;
>
> while this patch helps (no WARN() printed) I'm not sure this is the right fix.
> TDA998x is also used by armada DRM driver which has not been converted (yet) to
> atomic modesetting. And judging by the code and comment of drm_connector_get_encoder()
> in drm_crtc.c, having access to the encoder through the connector is the non-atomic
> way of doing things:
>
> static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
> {
> /* For atomic drivers only state objects are synchronously updated and
> * protected by modeset locks, so check those first. */
> if (connector->state)
> return connector->state->best_encoder;
> return connector->encoder;
> }
>
> To me, it looks like the WARN() is bogus when the atomic modesetting is used in
> drm_atomic_helper_update_legacy_modeset_state(). Either we acknowledge that the "legacy"
> code sets the connector in the encoder structure before complete pipeline is setup
> and we remove the WARN(), or we find a better way of detecting that some sort of mixed
> support is in place (i.e. atomic and non-atomic aware code running) and we clean up
> in a way that is compatible with both worlds.

I think the problem you're seeing here is specifically caused by drivers
setting up the connector->encoder explicitly. There should be no reason
to do that. The DRM core will automatically do that when setting up a
default configuration, or as a result of userspace setting up the wanted
configuration. You're also likely only seeing this the first time around
and subsequent calls will not trigger this anymore because at that point
the core will have reset connector->encoder to NULL as part of tearing
down the pipeline.

To corroborate that, the Tegra driver doesn't trigger this WARN_ON() and
also never sets up the connector->encoder manually. The same is probably
true for many other drivers that have already been converted. That said,
from a brief look it seems like many more drivers get this wrong and may
run into this WARN when they get converted to atomic.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]