ANDROID: binder: fix KMI issues due to frozen notification

The patches to support binder's frozen notification feature break the
KMI. This change fixes such issues by (1) moving proc->delivered_freeze
into the existing proc_wrapper struction, (2) dropping the frozen stats
support and (3) amending the STG due to a harmless enum binder_work_type
addition.

These are the reported KMI issues fixed by this patch:

  function symbol 'int __traceiter_binder_transaction_received(void*, struct binder_transaction*)' changed
    CRC changed from 0x74e9c98b to 0xfe0f8640

  type 'struct binder_proc' changed
    byte size changed from 584 to 632
    member 'struct list_head delivered_death' changed
      offset changed by 256
    member 'struct list_head delivered_freeze' was added
    13 members ('u32 max_threads' .. 'u64 android_oem_data1') changed
      offset changed by 384

  type 'struct binder_thread' changed
    byte size changed from 464 to 496
    2 members ('atomic_t tmp_ref' .. 'bool is_dead') changed
      offset changed by 224
    4 members ('struct task_struct* task' .. 'enum binder_prio_state prio_state') changed
      offset changed by 256

  type 'struct binder_stats' changed
    byte size changed from 216 to 244
    member changed from 'atomic_t br[21]' to 'atomic_t br[23]'
      type changed from 'atomic_t[21]' to 'atomic_t[23]'
        number of elements changed from 21 to 23
    member changed from 'atomic_t bc[19]' to 'atomic_t bc[22]'
      offset changed from 672 to 736
      type changed from 'atomic_t[19]' to 'atomic_t[22]'
        number of elements changed from 19 to 22
    member changed from 'atomic_t obj_created[7]' to 'atomic_t obj_created[8]'
      offset changed from 1280 to 1440
      type changed from 'atomic_t[7]' to 'atomic_t[8]'
        number of elements changed from 7 to 8
    member changed from 'atomic_t obj_deleted[7]' to 'atomic_t obj_deleted[8]'
      offset changed from 1504 to 1696
      type changed from 'atomic_t[7]' to 'atomic_t[8]'
        number of elements changed from 7 to 8

  type 'enum binder_work_type' changed
    enumerator 'BINDER_WORK_FROZEN_BINDER' (10) was added
    enumerator 'BINDER_WORK_CLEAR_FREEZE_NOTIFICATION' (11) was added

Bug: 363013421
Change-Id: If9f1f14a2eda215a4c9cb0823c50c8e0e8079ef1
Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
Carlos Llamas 2024-08-29 18:18:15 +00:00 committed by Ksawlii
parent 82d35f1efa
commit 4a0304ecc3
2 changed files with 16 additions and 18 deletions

View file

@ -3980,7 +3980,6 @@ binder_request_freeze_notification(struct binder_proc *proc,
is_frozen = ref->node->proc->is_frozen;
binder_inner_proc_unlock(ref->node->proc);
binder_stats_created(BINDER_STAT_FREEZE);
INIT_LIST_HEAD(&freeze->work.entry);
freeze->cookie = handle_cookie->cookie;
freeze->work.type = BINDER_WORK_FROZEN_BINDER;
@ -4066,7 +4065,7 @@ binder_freeze_notification_done(struct binder_proc *proc,
struct binder_work *w;
binder_inner_proc_lock(proc);
list_for_each_entry(w, &proc->delivered_freeze, entry) {
list_for_each_entry(w, &proc_wrapper(proc)->delivered_freeze, entry) {
struct binder_ref_freeze *tmp_freeze =
container_of(w, struct binder_ref_freeze, work);
@ -5018,7 +5017,7 @@ retry:
info.is_frozen = freeze->is_frozen;
info.cookie = freeze->cookie;
freeze->sent = true;
binder_enqueue_work_ilocked(w, &proc->delivered_freeze);
binder_enqueue_work_ilocked(w, &proc_wrapper(proc)->delivered_freeze);
binder_inner_proc_unlock(proc);
if (put_user(BR_FROZEN_BINDER, (uint32_t __user *)ptr))
@ -5038,7 +5037,6 @@ retry:
binder_inner_proc_unlock(proc);
kfree(freeze);
binder_stats_deleted(BINDER_STAT_FREEZE);
if (put_user(BR_CLEAR_FREEZE_NOTIFICATION_DONE, (uint32_t __user *)ptr))
return -EFAULT;
ptr += sizeof(uint32_t);
@ -6129,7 +6127,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
binder_stats_created(BINDER_STAT_PROC);
proc->pid = current->group_leader->pid;
INIT_LIST_HEAD(&proc->delivered_death);
INIT_LIST_HEAD(&proc->delivered_freeze);
INIT_LIST_HEAD(&proc_wrapper(proc)->delivered_freeze);
INIT_LIST_HEAD(&proc->waiting_threads);
filp->private_data = proc;
@ -6809,9 +6807,6 @@ static const char * const binder_return_strings[] = {
"BR_FAILED_REPLY",
"BR_FROZEN_REPLY",
"BR_ONEWAY_SPAM_SUSPECT",
"UNSUPPORTED",
"BR_FROZEN_BINDER",
"BR_CLEAR_FREEZE_NOTIFICATION_DONE",
};
static const char * const binder_command_strings[] = {
@ -6834,9 +6829,6 @@ static const char * const binder_command_strings[] = {
"BC_DEAD_BINDER_DONE",
"BC_TRANSACTION_SG",
"BC_REPLY_SG",
"BC_REQUEST_FREEZE_NOTIFICATION",
"BC_CLEAR_FREEZE_NOTIFICATION",
"BC_FREEZE_NOTIFICATION_DONE",
};
static const char * const binder_objstat_strings[] = {
@ -6847,7 +6839,6 @@ static const char * const binder_objstat_strings[] = {
"death",
"transaction",
"transaction_complete",
"freeze",
};
static void print_binder_stats(struct seq_file *m, const char *prefix,

View file

@ -129,13 +129,12 @@ enum binder_stat_types {
BINDER_STAT_DEATH,
BINDER_STAT_TRANSACTION,
BINDER_STAT_TRANSACTION_COMPLETE,
BINDER_STAT_FREEZE,
BINDER_STAT_COUNT
};
struct binder_stats {
atomic_t br[_IOC_NR(BR_CLEAR_FREEZE_NOTIFICATION_DONE) + 1];
atomic_t bc[_IOC_NR(BC_FREEZE_NOTIFICATION_DONE) + 1];
atomic_t br[_IOC_NR(BR_ONEWAY_SPAM_SUSPECT) + 1];
atomic_t bc[_IOC_NR(BC_REPLY_SG) + 1];
atomic_t obj_created[BINDER_STAT_COUNT];
atomic_t obj_deleted[BINDER_STAT_COUNT];
};
@ -159,8 +158,10 @@ struct binder_work {
BINDER_WORK_DEAD_BINDER,
BINDER_WORK_DEAD_BINDER_AND_CLEAR,
BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
#ifndef __GENKSYMS__
BINDER_WORK_FROZEN_BINDER,
BINDER_WORK_CLEAR_FREEZE_NOTIFICATION,
#endif
} type;
};
@ -405,8 +406,6 @@ struct binder_priority {
* (atomics, no lock needed)
* @delivered_death: list of delivered death notification
* (protected by @inner_lock)
* @delivered_freeze: list of delivered freeze notification
* (protected by @inner_lock)
* @max_threads: cap on number of binder threads
* (protected by @inner_lock)
* @requested_threads: number of binder threads requested but not
@ -453,7 +452,6 @@ struct binder_proc {
struct list_head todo;
struct binder_stats stats;
struct list_head delivered_death;
struct list_head delivered_freeze;
int max_threads;
int requested_threads;
int requested_threads_started;
@ -474,6 +472,8 @@ struct binder_proc {
* @cred struct cred associated with the `struct file`
* in binder_open()
* (invariant after initialized)
* @delivered_freeze: list of delivered freeze notification
* (protected by @inner_lock)
*
* Extended binder_proc -- needed to add the "cred" field without
* changing the KMI for binder_proc.
@ -481,6 +481,7 @@ struct binder_proc {
struct binder_proc_ext {
struct binder_proc proc;
const struct cred *cred;
struct list_head delivered_freeze;
};
static inline const struct cred *binder_get_cred(struct binder_proc *proc)
@ -491,6 +492,12 @@ static inline const struct cred *binder_get_cred(struct binder_proc *proc)
return eproc->cred;
}
static inline
struct binder_proc_ext *proc_wrapper(struct binder_proc *proc)
{
return container_of(proc, struct binder_proc_ext, proc);
}
/**
* struct binder_thread - binder thread bookkeeping
* @proc: binder process for this thread