drm/atomic_helper: Cope with plane->crtc == NULL in disable helper
authorJasper St. Pierre <jstpierre@mecheye.net>
Fri, 21 Nov 2014 03:59:15 +0000 (19:59 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 25 Nov 2014 12:12:43 +0000 (13:12 +0100)
The drm core can call the plane disable hook multiple times, which
means it can get called when plane->crtc is already NULL. That in turn
means we can't get at the implicit acquire ctx we use in the atomic
helpers for legacy entries points.

We could try to pass drm_modeset_legacy_acquire_ctx a drm_device
pointer so that it can cope with a NULL crtc. But that still doesn't
work since the cursor ioctls (remapped with the universal cursor plane
support code) only grabs the crtc locks. So the global acquire context
isn't set eitehr.

The real solution here would be to bite the bullet and wire up
explicit acquire context parameters to all relevant functions. We need
to do that anyway (to be able to get rid of some small allocations
which we can't cope with failing). But that's a lot of work and better
done once atomic has settled a bit.

So meanwhile just catch this case in the helper and bail out.

Signed-off-by: Jasper St. Pierre <jstpierre@mecheye.net>
Reviewed-by: Rob Clark <robdclark@gmail.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
[danvet: Completely rewrite commit message and comment but keep
Jasper's logic and author credits since his patch is the only
short-term solution that works.]
Tested-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/drm_atomic_helper.c

index 4368581ac1eb26a5daa36c8218d7a2096ef99289..d981d07d50cd0f13e8da3843a79b3d71c10a7570 100644 (file)
@@ -1275,6 +1275,17 @@ int drm_atomic_helper_disable_plane(struct drm_plane *plane)
        struct drm_plane_state *plane_state;
        int ret = 0;
 
+       /*
+        * FIXME: Without plane->crtc set we can't get at the implicit legacy
+        * acquire context. The real fix will be to wire the acquire ctx through
+        * everywhere we need it, but meanwhile prevent chaos by just skipping
+        * this noop. The critical case is the cursor ioctls which a) only grab
+        * crtc/cursor-plane locks (so we need the crtc to get at the right
+        * acquire context) and b) can try to disable the plane multiple times.
+        */
+       if (!plane->crtc)
+               return 0;
+
        state = drm_atomic_state_alloc(plane->dev);
        if (!state)
                return -ENOMEM;