drm/atomic: track bitmask of planes attached to crtc

Daniel Vetter daniel at ffwll.ch
Thu Nov 27 09:11:30 PST 2014


On Thu, Nov 27, 2014 at 06:54:03PM +0300, Dan Carpenter wrote:
> On Thu, Nov 27, 2014 at 10:55:02AM +0100, Daniel Vetter wrote:
> > On Thu, Nov 27, 2014 at 09:41:13AM +0300, Dan Carpenter wrote:
> > > Hello Rob Clark,
> > > 
> > > The patch 1ed2f34b4cc0: "drm/atomic: track bitmask of planes attached
> > > to crtc" from Nov 21, 2014, leads to the following static checker
> > > warning:
> > > 
> > > 	drivers/gpu/drm/drm_atomic.c:368 drm_atomic_set_crtc_for_plane()
> > > 	error: 'plane_state' dereferencing possible ERR_PTR()
> > 
> > Hm yeah that shouldn't ever happen when callers use this correctly. But a
> > WARN_ON would be good I guess. I'll add it.
> > 
> 
> It could fail because of allocation failures.  But maybe this is a boot
> time thing?  Normally dereferencing an ERR_PTR() is easy enough to debug
> and static checkers just ignore WARN_ONs.  I am ambivalent.

Well there rules are that you need to acquire the plane_state first. We're
now respinning the interfaces a bit to again make sure that's done by
requiring callers to directly pass in the plane_state.

btw not sure whether checker should just look through WARN_ON, we have
lots of places where we've historically screwed up and added a WARN_ON +
early return to make sure we'll in the future somewhat recover. This is
really important for gfx since at boot-up (due to fbcon locking bonghits)
the entire intial modeset is run with console_lock held. And that's a few
10k lines of code depending upon platform :(

So we absolutely have to handle failures robustely, but if checkers assume
that it's ok to pass crap caught by WARN_ONs around then that's might
reduce checker usefulness quite a bit.

Just an aside really

> > > 
> > > drivers/gpu/drm/drm_atomic.c
> > >    360  int
> > >    361  drm_atomic_set_crtc_for_plane(struct drm_atomic_state *state,
> > >    362                                struct drm_plane *plane, struct drm_crtc *crtc)
> > >    363  {
> > >    364          struct drm_plane_state *plane_state =
> > >                                         ^^^^^^^^^^^^^
> > >    365                          drm_atomic_get_plane_state(state, plane);
> > >                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > >    366          struct drm_crtc_state *crtc_state;
> > >    367  
> > >    368          if (plane_state->crtc) {
> > >                     ^^^^^^^^^^^^^^^^^
> > > Missing IS_ERR() check.
> > > 
> > > Also drm_atomic_get_plane_state() has poor error handling.  In
> > > drm_atomic_get_plane_state(), if the call to drm_atomic_get_plane_state()
> > > fails then it leaks memory.
> > 
> > Where does it leak memory exactly?
> 
> drivers/gpu/drm/drm_atomic.c
>    249  
>    250          plane_state = plane->funcs->atomic_duplicate_state(plane);
> 
> This is a kmemdup().

Another aside: it'll soon be more once a few drivers with atomic support
have merged. But fundamentally they'll all still need to do at least the
kmemdup.

>    251          if (!plane_state)
>    252                  return ERR_PTR(-ENOMEM);
>    253  
>    254          state->plane_states[index] = plane_state;

This statement here should make sure that drm_atomic_state_free cleans
everthing up. So I still don't see a leak ... where does the checker see
one?

>    255          state->planes[index] = plane;
>    256          plane_state->state = state;
>    257  
>    258          DRM_DEBUG_KMS("Added [PLANE:%d] %p state to %p\n",
>    259                        plane->base.id, plane_state, state);
>    260  
>    261          if (plane_state->crtc) {
>    262                  struct drm_crtc_state *crtc_state;
>    263  
>    264                  crtc_state = drm_atomic_get_crtc_state(state,
>    265                                                         plane_state->crtc);
>    266                  if (IS_ERR(crtc_state))
>    267                          return ERR_CAST(crtc_state);
> 
> We leak if we return here.

Note that the atomic stuff is using wait/wound mutexes, so bailing out
with -EDEADLK into the slowpath is an expected path. Hence why we tend to
keep all the allocs around until we eventually get rid of them in one
spot.
-Daniel

> 
>    268          }
>    269  
>    270          return plane_state;
> 
> regards,
> dan carpenter

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


More information about the dri-devel mailing list