From 0853695c3ba46f97dfc0b5885f7b7e640ca212dd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 14 Oct 2016 13:18:18 +0100 Subject: drm: Add reference counting to drm_atomic_state drm_atomic_state has a complicated single owner model that tracks the single reference from allocation through to destruction on another thread - or perhaps on a local error path. We can simplify this tracking by using reference counting (at a cost of a few more atomics). This is even more beneficial when the lifetime of the state becomes more convoluted than being passed to a single worker thread for the commit. v2: Double check !intel atomic_commit functions for missing gets v3: Update kerneldocs Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Reviewed-by: Eric Engestrom Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161014121833.439-27-chris@chris-wilson.co.uk --- include/drm/drm_atomic.h | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'include/drm/drm_atomic.h') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index c52f99415c55..fc8af53b18aa 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -153,6 +153,7 @@ struct __drm_connnectors_state { /** * struct drm_atomic_state - the global state object for atomic updates + * @ref: count of all references to this state (will not be freed until zero) * @dev: parent DRM device * @allow_modeset: allow full modeset * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics @@ -164,6 +165,8 @@ struct __drm_connnectors_state { * @acquire_ctx: acquire context for this atomic modeset state update */ struct drm_atomic_state { + struct kref ref; + struct drm_device *dev; bool allow_modeset : 1; bool legacy_cursor_update : 1; @@ -193,7 +196,33 @@ static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) struct drm_atomic_state * __must_check drm_atomic_state_alloc(struct drm_device *dev); void drm_atomic_state_clear(struct drm_atomic_state *state); -void drm_atomic_state_free(struct drm_atomic_state *state); + +/** + * drm_atomic_state_get - acquire a reference to the atomic state + * @state: The atomic state + * + * Returns a new reference to the @state + */ +static inline struct drm_atomic_state * +drm_atomic_state_get(struct drm_atomic_state *state) +{ + kref_get(&state->ref); + return state; +} + +void __drm_atomic_state_free(struct kref *ref); + +/** + * drm_atomic_state_put - release a reference to the atomic state + * @state: The atomic state + * + * This releases a reference to @state which is freed after removing the + * final reference. No locking required and callable from any context. + */ +static inline void drm_atomic_state_put(struct drm_atomic_state *state) +{ + kref_put(&state->ref, __drm_atomic_state_free); +} int __must_check drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state); -- cgit v1.2.3-55-g7522