bcm27xx: switch to 5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.10 / 950-0681-drm-Introduce-an-atomic_commit_setup-function.patch
1 From 86fc6b59ae170399aaf8fd9880f1a3f79948f5a3 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Fri, 4 Dec 2020 16:11:32 +0100
4 Subject: [PATCH] drm: Introduce an atomic_commit_setup function
5
6 Private objects storing a state shared across all CRTCs need to be
7 carefully handled to avoid a use-after-free issue.
8
9 The proper way to do this to track all the commits using that shared
10 state and wait for the previous commits to be done before going on with
11 the current one to avoid the reordering of commits that could occur.
12
13 However, this commit setup needs to be done after
14 drm_atomic_helper_setup_commit(), because before the CRTC commit
15 structure hasn't been allocated before, and before the workqueue is
16 scheduled, because we would be potentially reordered already otherwise.
17
18 That means that drivers currently have to roll their own
19 drm_atomic_helper_commit() function, even though it would be identical
20 if not for the commit setup.
21
22 Let's introduce a hook to do so that would be called as part of
23 drm_atomic_helper_commit, allowing us to reuse the atomic helpers.
24
25 Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
26 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
27 ---
28 drivers/gpu/drm/drm_atomic_helper.c | 9 +++++++++
29 include/drm/drm_modeset_helper_vtables.h | 21 +++++++++++++++++++++
30 2 files changed, 30 insertions(+)
31
32 --- a/drivers/gpu/drm/drm_atomic_helper.c
33 +++ b/drivers/gpu/drm/drm_atomic_helper.c
34 @@ -2039,6 +2039,9 @@ crtc_or_fake_commit(struct drm_atomic_st
35 * should always call this function from their
36 * &drm_mode_config_funcs.atomic_commit hook.
37 *
38 + * Drivers that need to extend the commit setup to private objects can use the
39 + * &drm_mode_config_helper_funcs.atomic_commit_setup hook.
40 + *
41 * To be able to use this support drivers need to use a few more helper
42 * functions. drm_atomic_helper_wait_for_dependencies() must be called before
43 * actually committing the hardware state, and for nonblocking commits this call
44 @@ -2082,8 +2085,11 @@ int drm_atomic_helper_setup_commit(struc
45 struct drm_plane *plane;
46 struct drm_plane_state *old_plane_state, *new_plane_state;
47 struct drm_crtc_commit *commit;
48 + const struct drm_mode_config_helper_funcs *funcs;
49 int i, ret;
50
51 + funcs = state->dev->mode_config.helper_private;
52 +
53 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
54 commit = kzalloc(sizeof(*commit), GFP_KERNEL);
55 if (!commit)
56 @@ -2160,6 +2166,9 @@ int drm_atomic_helper_setup_commit(struc
57 new_plane_state->commit = drm_crtc_commit_get(commit);
58 }
59
60 + if (funcs && funcs->atomic_commit_setup)
61 + return funcs->atomic_commit_setup(state);
62 +
63 return 0;
64 }
65 EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
66 --- a/include/drm/drm_modeset_helper_vtables.h
67 +++ b/include/drm/drm_modeset_helper_vtables.h
68 @@ -1396,6 +1396,27 @@ struct drm_mode_config_helper_funcs {
69 * drm_atomic_helper_commit_tail().
70 */
71 void (*atomic_commit_tail)(struct drm_atomic_state *state);
72 +
73 + /**
74 + * @atomic_commit_setup:
75 + *
76 + * This hook is used by the default atomic_commit() hook implemented in
77 + * drm_atomic_helper_commit() together with the nonblocking helpers (see
78 + * drm_atomic_helper_setup_commit()) to extend the DRM commit setup. It
79 + * is not used by the atomic helpers.
80 + *
81 + * This function is called at the end of
82 + * drm_atomic_helper_setup_commit(), so once the commit has been
83 + * properly setup across the generic DRM object states. It allows
84 + * drivers to do some additional commit tracking that isn't related to a
85 + * CRTC, plane or connector, tracked in a &drm_private_obj structure.
86 + *
87 + * Note that the documentation of &drm_private_obj has more details on
88 + * how one should implement this.
89 + *
90 + * This hook is optional.
91 + */
92 + int (*atomic_commit_setup)(struct drm_atomic_state *state);
93 };
94
95 #endif