[PATCH v4 07/13] drm/atomic: Create function to insert private obj state into a commit

From: Maxime Ripard

Date: Fri Sep 18 2026 - 10:55:08 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 | 53 +++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 807b575ecc54..513e91ad2fdc 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1093,10 +1093,39 @@ 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;
+
+ drm_modeset_lock_assert_held(&obj->lock);
+
+ num_objs = commit->num_private_objs + 1;
+ arr = krealloc_array(commit->private_objs, num_objs,
+ sizeof(*commit->private_objs), GFP_KERNEL | __GFP_ZERO);
+ if (!arr)
+ return -ENOMEM;
+
+ commit->private_objs = arr;
+ index = commit->num_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
*
@@ -1109,12 +1138,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;
- 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);

@@ -1124,30 +1152,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;
- arr = krealloc_array(state->private_objs, num_objs,
- sizeof(*state->private_objs), GFP_KERNEL | __GFP_ZERO);
- if (!arr)
- return ERR_PTR(-ENOMEM);
-
- state->private_objs = arr;
- index = state->num_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.55.0