summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_atomic_helper.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime@cerno.tech>2020-12-04 16:11:32 +0100
committerMaxime Ripard <maxime@cerno.tech>2020-12-15 11:33:08 +0100
commitddadd40892f31a6653cf104e274f7d2ae764eabb (patch)
treea2bce041f5b789cfe67dab749677b62769a0b995 /drivers/gpu/drm/drm_atomic_helper.c
parentae75a0431f822273ce5d3a574863c67503db5775 (diff)
drm: Introduce an atomic_commit_setup function
Private objects storing a state shared across all CRTCs need to be carefully handled to avoid a use-after-free issue. The proper way to do this to track all the commits using that shared state and wait for the previous commits to be done before going on with the current one to avoid the reordering of commits that could occur. However, this commit setup needs to be done after drm_atomic_helper_setup_commit(), because before the CRTC commit structure hasn't been allocated before, and before the workqueue is scheduled, because we would be potentially reordered already otherwise. That means that drivers currently have to roll their own drm_atomic_helper_commit() function, even though it would be identical if not for the commit setup. Let's introduce a hook to do so that would be called as part of drm_atomic_helper_commit, allowing us to reuse the atomic helpers. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20201204151138.1739736-2-maxime@cerno.tech
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ba1507036f26..7fcf91ecb1d9 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2040,6 +2040,9 @@ crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc)
* should always call this function from their
* &drm_mode_config_funcs.atomic_commit hook.
*
+ * Drivers that need to extend the commit setup to private objects can use the
+ * &drm_mode_config_helper_funcs.atomic_commit_setup hook.
+ *
* To be able to use this support drivers need to use a few more helper
* functions. drm_atomic_helper_wait_for_dependencies() must be called before
* actually committing the hardware state, and for nonblocking commits this call
@@ -2083,8 +2086,11 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
struct drm_plane *plane;
struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_crtc_commit *commit;
+ const struct drm_mode_config_helper_funcs *funcs;
int i, ret;
+ funcs = state->dev->mode_config.helper_private;
+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
commit = kzalloc(sizeof(*commit), GFP_KERNEL);
if (!commit)
@@ -2169,6 +2175,9 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
new_plane_state->commit = drm_crtc_commit_get(commit);
}
+ if (funcs && funcs->atomic_commit_setup)
+ return funcs->atomic_commit_setup(state);
+
return 0;
}
EXPORT_SYMBOL(drm_atomic_helper_setup_commit);