]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
binder: pre-allocate binder_transaction
authorCarlos Llamas <cmllamas@google.com>
Sun, 27 Jul 2025 18:29:04 +0000 (18:29 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Aug 2025 10:53:01 +0000 (12:53 +0200)
Move the allocation of 'struct binder_transaction' to the beginning of
the binder_transaction() function, along with the initialization of all
the members that are known at that time. This minor refactoring helps to
consolidate the usage of transaction information at later points.

This patch is in preparation for binder's generic netlink implementation
and no functional changes are intended.

Signed-off-by: Carlos Llamas <cmllamas@google.com>
Link: https://lore.kernel.org/r/20250727182932.2499194-2-cmllamas@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/android/binder.c

index 28634f786e701247a924543c9dd79fc3ac4f3026..d1d1051cdedb1c7b9acc8edd720084dcdd63cd57 100644 (file)
@@ -3042,6 +3042,30 @@ static void binder_transaction(struct binder_proc *proc,
        binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0);
        binder_inner_proc_unlock(proc);
 
+       t = kzalloc(sizeof(*t), GFP_KERNEL);
+       if (!t) {
+               binder_txn_error("%d:%d cannot allocate transaction\n",
+                                thread->pid, proc->pid);
+               return_error = BR_FAILED_REPLY;
+               return_error_param = -ENOMEM;
+               return_error_line = __LINE__;
+               goto err_alloc_t_failed;
+       }
+       INIT_LIST_HEAD(&t->fd_fixups);
+       binder_stats_created(BINDER_STAT_TRANSACTION);
+       spin_lock_init(&t->lock);
+       t->debug_id = t_debug_id;
+       t->start_time = t_start_time;
+       t->from_pid = proc->pid;
+       t->from_tid = thread->pid;
+       t->sender_euid = task_euid(proc->tsk);
+       t->code = tr->code;
+       t->flags = tr->flags;
+       t->priority = task_nice(current);
+       t->work.type = BINDER_WORK_TRANSACTION;
+       if (!reply && !(tr->flags & TF_ONE_WAY))
+               t->from = thread;
+
        if (reply) {
                binder_inner_proc_lock(proc);
                in_reply_to = thread->transaction_stack;
@@ -3228,24 +3252,13 @@ static void binder_transaction(struct binder_proc *proc,
                }
                binder_inner_proc_unlock(proc);
        }
+
+       t->to_proc = target_proc;
+       t->to_thread = target_thread;
        if (target_thread)
                e->to_thread = target_thread->pid;
        e->to_proc = target_proc->pid;
 
-       /* TODO: reuse incoming transaction for reply */
-       t = kzalloc(sizeof(*t), GFP_KERNEL);
-       if (t == NULL) {
-               binder_txn_error("%d:%d cannot allocate transaction\n",
-                       thread->pid, proc->pid);
-               return_error = BR_FAILED_REPLY;
-               return_error_param = -ENOMEM;
-               return_error_line = __LINE__;
-               goto err_alloc_t_failed;
-       }
-       INIT_LIST_HEAD(&t->fd_fixups);
-       binder_stats_created(BINDER_STAT_TRANSACTION);
-       spin_lock_init(&t->lock);
-
        tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
        if (tcomplete == NULL) {
                binder_txn_error("%d:%d cannot allocate work for transaction\n",
@@ -3257,9 +3270,6 @@ static void binder_transaction(struct binder_proc *proc,
        }
        binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
 
-       t->debug_id = t_debug_id;
-       t->start_time = t_start_time;
-
        if (reply)
                binder_debug(BINDER_DEBUG_TRANSACTION,
                             "%d:%d BC_REPLY %d -> %d:%d, data size %lld-%lld-%lld\n",
@@ -3275,19 +3285,6 @@ static void binder_transaction(struct binder_proc *proc,
                             (u64)tr->data_size, (u64)tr->offsets_size,
                             (u64)extra_buffers_size);
 
-       if (!reply && !(tr->flags & TF_ONE_WAY))
-               t->from = thread;
-       else
-               t->from = NULL;
-       t->from_pid = proc->pid;
-       t->from_tid = thread->pid;
-       t->sender_euid = task_euid(proc->tsk);
-       t->to_proc = target_proc;
-       t->to_thread = target_thread;
-       t->code = tr->code;
-       t->flags = tr->flags;
-       t->priority = task_nice(current);
-
        if (target_node && target_node->txn_security_ctx) {
                u32 secid;
                size_t added_size;
@@ -3684,7 +3681,6 @@ static void binder_transaction(struct binder_proc *proc,
                tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
        else
                tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
-       t->work.type = BINDER_WORK_TRANSACTION;
 
        if (reply) {
                binder_enqueue_thread_work(thread, tcomplete);
@@ -3783,9 +3779,6 @@ err_get_secctx_failed:
 err_alloc_tcomplete_failed:
        if (trace_binder_txn_latency_free_enabled())
                binder_txn_latency_free(t);
-       kfree(t);
-       binder_stats_deleted(BINDER_STAT_TRANSACTION);
-err_alloc_t_failed:
 err_bad_todo_list:
 err_bad_call_stack:
 err_empty_call_stack:
@@ -3795,6 +3788,9 @@ err_invalid_target_handle:
                binder_dec_node(target_node, 1, 0);
                binder_dec_node_tmpref(target_node);
        }
+       kfree(t);
+       binder_stats_deleted(BINDER_STAT_TRANSACTION);
+err_alloc_t_failed:
 
        binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
                     "%d:%d transaction %s to %d:%d failed %d/%d/%d, code %u size %lld-%lld line %d\n",