[PATCH RFC 5/8] drm/atomic: Create function to insert private obj state into a commit
From: Maxime Ripard
Date: Wed Jul 08 2026 - 12:28:24 EST
drm_atomic_get_private_obj_state() allocates a new private object
state by duplicating the current one and inserts it into the atomic
commit as a single operation.
However, a later change will need to insert a private object state
into a commit without going through the full allocation and
duplication path in drm_atomic_get_private_obj_state().
Extract the state insertion logic, including the array reallocation,
into a new static drm_atomic_commit_set_private_obj_state() helper,
and convert drm_atomic_get_private_obj_state() to use it.
Signed-off-by: Maxime Ripard <mripard@xxxxxxxxxx>
---
drivers/gpu/drm/drm_atomic.c | 57 ++++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index f006de9b7263..d4dcab2d851c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1097,10 +1097,41 @@ drm_atomic_private_obj_fini(struct drm_private_obj *obj)
obj->funcs->atomic_destroy_state(obj, obj->state);
drm_modeset_lock_fini(&obj->lock);
}
EXPORT_SYMBOL(drm_atomic_private_obj_fini);
+static int drm_atomic_commit_set_private_obj_state(struct drm_atomic_commit *commit,
+ struct drm_private_obj *obj,
+ struct drm_private_state *obj_state)
+{
+ struct __drm_private_objs_state *arr;
+ int index, num_objs;
+ size_t size;
+
+ drm_modeset_lock_assert_held(&obj->lock);
+
+ num_objs = commit->num_private_objs + 1;
+ size = sizeof(*commit->private_objs) * num_objs;
+ arr = krealloc(commit->private_objs, size, GFP_KERNEL);
+ if (!arr)
+ return -ENOMEM;
+
+ commit->private_objs = arr;
+ index = commit->num_private_objs;
+ memset(&commit->private_objs[index], 0, sizeof(*commit->private_objs));
+
+ commit->private_objs[index].state_to_destroy = obj_state;
+ commit->private_objs[index].old_state = obj->state;
+ commit->private_objs[index].new_state = obj_state;
+ commit->private_objs[index].ptr = obj;
+ obj_state->state = commit;
+
+ commit->num_private_objs = num_objs;
+
+ return 0;
+}
+
/**
* drm_atomic_get_private_obj_state - get private object state
* @state: global atomic state
* @obj: private object to get the state for
*
@@ -1113,13 +1144,11 @@ EXPORT_SYMBOL(drm_atomic_private_obj_fini);
*/
struct drm_private_state *
drm_atomic_get_private_obj_state(struct drm_atomic_commit *state,
struct drm_private_obj *obj)
{
- int index, num_objs, ret;
- size_t size;
- struct __drm_private_objs_state *arr;
+ int ret;
struct drm_private_state *obj_state;
WARN_ON(!state->acquire_ctx);
drm_WARN_ON(state->dev, state->checked);
@@ -1129,31 +1158,19 @@ drm_atomic_get_private_obj_state(struct drm_atomic_commit *state,
ret = drm_modeset_lock(&obj->lock, state->acquire_ctx);
if (ret)
return ERR_PTR(ret);
- num_objs = state->num_private_objs + 1;
- size = sizeof(*state->private_objs) * num_objs;
- arr = krealloc(state->private_objs, size, GFP_KERNEL);
- if (!arr)
- return ERR_PTR(-ENOMEM);
-
- state->private_objs = arr;
- index = state->num_private_objs;
- memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
-
obj_state = obj->funcs->atomic_duplicate_state(obj);
if (!obj_state)
return ERR_PTR(-ENOMEM);
- state->private_objs[index].state_to_destroy = obj_state;
- state->private_objs[index].old_state = obj->state;
- state->private_objs[index].new_state = obj_state;
- state->private_objs[index].ptr = obj;
- obj_state->state = state;
-
- state->num_private_objs = num_objs;
+ ret = drm_atomic_commit_set_private_obj_state(state, obj, obj_state);
+ if (ret) {
+ obj->funcs->atomic_destroy_state(obj, obj_state);
+ return ERR_PTR(ret);
+ }
drm_dbg_atomic(state->dev,
"Added new private object %p state %p to %p\n",
obj, obj_state, state);
--
2.54.0