I've missed checking this and so didn't notice that there's a NULL check missing. Since depending upon calling context the crtc might not even be there (disable-me-harder does happen around planes, especially in cleanup code) we need to dodge the oops and look at the global acquire ctx. v2: Actually fix the oops for real and don't just move it two lines down. That requires that we pass a drm_device pointer for the cases where crtc could be NULL. Reported-by: "Jasper St. Pierre" <jstpierre@xxxxxxxxxxx> Cc: "Jasper St. Pierre" <jstpierre@xxxxxxxxxxx> Cc: Rob Clark <robdclark@xxxxxxxxx> Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxxx> --- drivers/gpu/drm/drm_atomic_helper.c | 12 ++++++++---- drivers/gpu/drm/drm_modeset_lock.c | 12 ++++++++---- include/drm/drm_modeset_lock.h | 3 ++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ca839bd9bb0d..32c34b5d5f68 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1171,7 +1171,8 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane, if (!state) return -ENOMEM; - state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc, + plane->dev); retry: plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { @@ -1239,7 +1240,8 @@ int drm_atomic_helper_disable_plane(struct drm_plane *plane) if (!state) return -ENOMEM; - state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc); + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc, + plane->dev); retry: plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { @@ -1391,7 +1393,8 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set) if (!state) return -ENOMEM; - state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc, + crtc->dev); retry: crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) { @@ -1676,7 +1679,8 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, if (!state) return -ENOMEM; - state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc, + crtc->dev); retry: crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) { diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 474e4d12a2d8..655958d4f23e 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -200,21 +200,25 @@ EXPORT_SYMBOL(drm_modeset_lock_crtc); /** * drm_modeset_legacy_acquire_ctx - find acquire ctx for legacy ioctls * @crtc: drm crtc + * @dev: device * * Legacy ioctl operations like cursor updates or page flips only have per-crtc * locking, and store the acquire ctx in the corresponding crtc. All other * legacy operations take all locks and use a global acquire context. This * function grabs the right one. + * + * Note that either @crtc or @dev can be NULL, but not both. */ struct drm_modeset_acquire_ctx * -drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc) +drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc, + struct drm_device *dev) { - if (crtc->acquire_ctx) + if (crtc && crtc->acquire_ctx) return crtc->acquire_ctx; - WARN_ON(!crtc->dev->mode_config.acquire_ctx); + WARN_ON(!dev->mode_config.acquire_ctx); - return crtc->dev->mode_config.acquire_ctx; + return dev->mode_config.acquire_ctx; } EXPORT_SYMBOL(drm_modeset_legacy_acquire_ctx); diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index 28931a23d96c..cdbfd822e52f 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -135,7 +135,8 @@ void drm_modeset_lock_crtc(struct drm_crtc *crtc); void drm_modeset_unlock_crtc(struct drm_crtc *crtc); void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); struct drm_modeset_acquire_ctx * -drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc); +drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc, + struct drm_device *dev); int drm_modeset_lock_all_crtcs(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); -- 2.1.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel