Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7ea04d2 authored by Sean Paul's avatar Sean Paul
Browse files

drm: Add DRM_MODESET_LOCK_BEGIN/END helpers



This patch adds a couple of helpers to remove the boilerplate involved
in grabbing all of the modeset locks.

I've also converted the obvious cases in drm core to use the helpers.

The only remaining instance of drm_modeset_lock_all_ctx() is in
drm_framebuffer. It's complicated by the state clear that occurs on
deadlock. ATM, there's no way to inject code in the deadlock path with
the helpers, so it's unfit for conversion.

Changes in v2:
- Relocate ret argument to the end of the list (Daniel)
- Incorporate Daniel's doc suggestions (Daniel)

Suggested-by: default avatarDaniel Vetter <daniel@ffwll.ch>
Reviewed-by: default avatarDaniel Vetter <daniel@ffwll.ch>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20181129150423.239081-4-sean@poorly.run
parent 2aa3eef8
Loading
Loading
Loading
Loading
+10 −41
Original line number Diff line number Diff line
@@ -3128,23 +3128,13 @@ void drm_atomic_helper_shutdown(struct drm_device *dev)
	struct drm_modeset_acquire_ctx ctx;
	int ret;

	drm_modeset_acquire_init(&ctx, 0);
	while (1) {
		ret = drm_modeset_lock_all_ctx(dev, &ctx);
		if (!ret)
			ret = __drm_atomic_helper_disable_all(dev, &ctx, true);

		if (ret != -EDEADLK)
			break;

		drm_modeset_backoff(&ctx);
	}
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);

	ret = __drm_atomic_helper_disable_all(dev, &ctx, true);
	if (ret)
		DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);

	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	DRM_MODESET_LOCK_ALL_END(ctx, ret);
}
EXPORT_SYMBOL(drm_atomic_helper_shutdown);

@@ -3179,14 +3169,7 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
	struct drm_atomic_state *state;
	int err;

	drm_modeset_acquire_init(&ctx, 0);

retry:
	err = drm_modeset_lock_all_ctx(dev, &ctx);
	if (err < 0) {
		state = ERR_PTR(err);
		goto unlock;
	}
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);

	state = drm_atomic_helper_duplicate_state(dev, &ctx);
	if (IS_ERR(state))
@@ -3200,13 +3183,10 @@ struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
	}

unlock:
	if (PTR_ERR(state) == -EDEADLK) {
		drm_modeset_backoff(&ctx);
		goto retry;
	}
	DRM_MODESET_LOCK_ALL_END(ctx, err);
	if (err)
		return ERR_PTR(err);

	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	return state;
}
EXPORT_SYMBOL(drm_atomic_helper_suspend);
@@ -3280,22 +3260,11 @@ int drm_atomic_helper_resume(struct drm_device *dev,

	drm_mode_config_reset(dev);

	drm_modeset_acquire_init(&ctx, 0);
	while (1) {
		err = drm_modeset_lock_all_ctx(dev, &ctx);
		if (err)
			goto out;
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);

	err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
out:
		if (err != -EDEADLK)
			break;

		drm_modeset_backoff(&ctx);
	}

	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	DRM_MODESET_LOCK_ALL_END(ctx, err);
	drm_atomic_state_put(state);

	return err;
+2 −12
Original line number Diff line number Diff line
@@ -255,11 +255,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
	if (crtc_lut->gamma_size != crtc->gamma_size)
		return -EINVAL;

	drm_modeset_acquire_init(&ctx, 0);
retry:
	ret = drm_modeset_lock_all_ctx(dev, &ctx);
	if (ret)
		goto out;
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);

	size = crtc_lut->gamma_size * (sizeof(uint16_t));
	r_base = crtc->gamma_store;
@@ -284,13 +280,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
				     crtc->gamma_size, &ctx);

out:
	if (ret == -EDEADLK) {
		drm_modeset_backoff(&ctx);
		goto retry;
	}
	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);

	DRM_MODESET_LOCK_ALL_END(ctx, ret);
	return ret;

}
+3 −12
Original line number Diff line number Diff line
@@ -599,11 +599,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
	plane = crtc->primary;

	mutex_lock(&crtc->dev->mode_config.mutex);
	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
retry:
	ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
	if (ret)
		goto out;
	DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
				   DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);

	if (crtc_req->mode_valid) {
		/* If we have a mode we need a framebuffer. */
@@ -768,13 +765,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
	fb = NULL;
	mode = NULL;

	if (ret == -EDEADLK) {
		ret = drm_modeset_backoff(&ctx);
		if (!ret)
			goto retry;
	}
	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	DRM_MODESET_LOCK_ALL_END(ctx, ret);
	mutex_unlock(&crtc->dev->mode_config.mutex);

	return ret;
+6 −0
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@
 *     drm_modeset_drop_locks(ctx);
 *     drm_modeset_acquire_fini(ctx);
 *
 * For convenience this control flow is implemented in
 * DRM_MODESET_LOCK_ALL_BEGIN() and DRM_MODESET_LOCK_ALL_END() for the case
 * where all modeset locks need to be taken through drm_modeset_lock_all_ctx().
 *
 * If all that is needed is a single modeset lock, then the &struct
 * drm_modeset_acquire_ctx is not needed and the locking can be simplified
 * by passing a NULL instead of ctx in the drm_modeset_lock() call or
@@ -383,6 +387,8 @@ EXPORT_SYMBOL(drm_modeset_unlock);
 * Locks acquired with this function should be released by calling the
 * drm_modeset_drop_locks() function on @ctx.
 *
 * See also: DRM_MODESET_LOCK_ALL_BEGIN() and DRM_MODESET_LOCK_ALL_END()
 *
 * Returns: 0 on success or a negative error-code on failure.
 */
int drm_modeset_lock_all_ctx(struct drm_device *dev,
+3 −13
Original line number Diff line number Diff line
@@ -767,11 +767,8 @@ static int setplane_internal(struct drm_plane *plane,
	struct drm_modeset_acquire_ctx ctx;
	int ret;

	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
retry:
	ret = drm_modeset_lock_all_ctx(plane->dev, &ctx);
	if (ret)
		goto fail;
	DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx,
				   DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);

	if (drm_drv_uses_atomic_modeset(plane->dev))
		ret = __setplane_atomic(plane, crtc, fb,
@@ -782,14 +779,7 @@ static int setplane_internal(struct drm_plane *plane,
					  crtc_x, crtc_y, crtc_w, crtc_h,
					  src_x, src_y, src_w, src_h, &ctx);

fail:
	if (ret == -EDEADLK) {
		ret = drm_modeset_backoff(&ctx);
		if (!ret)
			goto retry;
	}
	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	DRM_MODESET_LOCK_ALL_END(ctx, ret);

	return ret;
}
Loading