lkml.org 
[lkml]   [2021]   [Mar]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 3/3] binder: BINDER_GET_FROZEN_INFO ioctl
    Date
    From: Marco Ballesio <balejs@google.com>

    User space needs to know if binder transactions occurred to frozen
    processes. Introduce a new BINDER_GET_FROZEN ioctl and keep track of
    transactions occurring to frozen proceses.

    Signed-off-by: Marco Ballesio <balejs@google.com>
    Signed-off-by: Li Li <dualli@google.com>
    ---
    drivers/android/binder.c | 55 +++++++++++++++++++++++++++++
    drivers/android/binder_internal.h | 6 ++++
    include/uapi/linux/android/binder.h | 7 ++++
    3 files changed, 68 insertions(+)

    diff --git a/drivers/android/binder.c b/drivers/android/binder.c
    index fe16c455a76e..e1a484ab0366 100644
    --- a/drivers/android/binder.c
    +++ b/drivers/android/binder.c
    @@ -2360,6 +2360,10 @@ static int binder_proc_transaction(struct binder_transaction *t,
    }

    binder_inner_proc_lock(proc);
    + if (proc->is_frozen) {
    + proc->sync_recv |= !oneway;
    + proc->async_recv |= oneway;
    + }

    if ((proc->is_frozen && !oneway) || proc->is_dead ||
    (thread && thread->is_dead)) {
    @@ -4634,6 +4638,8 @@ static int binder_ioctl_freeze(struct binder_freeze_info *info,

    if (!info->enable) {
    binder_inner_proc_lock(target_proc);
    + target_proc->sync_recv = false;
    + target_proc->async_recv = false;
    target_proc->is_frozen = false;
    binder_inner_proc_unlock(target_proc);
    return 0;
    @@ -4645,6 +4651,8 @@ static int binder_ioctl_freeze(struct binder_freeze_info *info,
    * for transactions to drain.
    */
    binder_inner_proc_lock(target_proc);
    + target_proc->sync_recv = false;
    + target_proc->async_recv = false;
    target_proc->is_frozen = true;
    binder_inner_proc_unlock(target_proc);

    @@ -4666,6 +4674,33 @@ static int binder_ioctl_freeze(struct binder_freeze_info *info,
    return ret;
    }

    +static int binder_ioctl_get_freezer_info(
    + struct binder_frozen_status_info *info)
    +{
    + struct binder_proc *target_proc;
    + bool found = false;
    +
    + info->sync_recv = 0;
    + info->async_recv = 0;
    +
    + mutex_lock(&binder_procs_lock);
    + hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
    + if (target_proc->pid == info->pid) {
    + found = true;
    + binder_inner_proc_lock(target_proc);
    + info->sync_recv |= target_proc->sync_recv;
    + info->async_recv |= target_proc->async_recv;
    + binder_inner_proc_unlock(target_proc);
    + }
    + }
    + mutex_unlock(&binder_procs_lock);
    +
    + if (!found)
    + return -EINVAL;
    +
    + return 0;
    +}
    +
    static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    {
    int ret;
    @@ -4844,6 +4879,24 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    goto err;
    break;
    }
    + case BINDER_GET_FROZEN_INFO: {
    + struct binder_frozen_status_info info;
    +
    + if (copy_from_user(&info, ubuf, sizeof(info))) {
    + ret = -EFAULT;
    + goto err;
    + }
    +
    + ret = binder_ioctl_get_freezer_info(&info);
    + if (ret < 0)
    + goto err;
    +
    + if (copy_to_user(ubuf, &info, sizeof(info))) {
    + ret = -EFAULT;
    + goto err;
    + }
    + break;
    + }
    default:
    ret = -EINVAL;
    goto err;
    @@ -5154,6 +5207,8 @@ static void binder_deferred_release(struct binder_proc *proc)

    proc->is_dead = true;
    proc->is_frozen = false;
    + proc->sync_recv = false;
    + proc->async_recv = false;
    threads = 0;
    active_transactions = 0;
    while ((n = rb_first(&proc->threads))) {
    diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h
    index e6a53e98c6da..2872a7de68e1 100644
    --- a/drivers/android/binder_internal.h
    +++ b/drivers/android/binder_internal.h
    @@ -376,6 +376,10 @@ struct binder_ref {
    * @is_frozen: process is frozen and unable to service
    * binder transactions
    * (protected by @inner_lock)
    + * @sync_recv: process received sync transactions since last frozen
    + * (protected by @inner_lock)
    + * @async_recv: process received async transactions since last frozen
    + * (protected by @inner_lock)
    * @freeze_wait: waitqueue of processes waiting for all outstanding
    * transactions to be processed
    * (protected by @inner_lock)
    @@ -422,6 +426,8 @@ struct binder_proc {
    int outstanding_txns;
    bool is_dead;
    bool is_frozen;
    + bool sync_recv;
    + bool async_recv;
    wait_queue_head_t freeze_wait;

    struct list_head todo;
    diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h
    index 7eb5b818b3c1..156070d18c4f 100644
    --- a/include/uapi/linux/android/binder.h
    +++ b/include/uapi/linux/android/binder.h
    @@ -223,6 +223,12 @@ struct binder_freeze_info {
    __u32 timeout_ms;
    };

    +struct binder_frozen_status_info {
    + __u32 pid;
    + __u32 sync_recv;
    + __u32 async_recv;
    +};
    +
    #define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
    #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
    #define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
    @@ -234,6 +240,7 @@ struct binder_freeze_info {
    #define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
    #define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
    #define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
    +#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)

    /*
    * NOTE: Two special error codes you should check for when calling
    --
    2.31.0.rc2.261.g7f71774620-goog
    \
     
     \ /
      Last update: 2021-03-16 02:18    [W:2.715 / U:0.932 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site