Skip to content

Commit

Permalink
FROMGIT: binder: BINDER_GET_FROZEN_INFO ioctl
Browse files Browse the repository at this point in the history
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.

Bug: 180989544
(cherry picked from commit c55019c24b22d6770bd8e2f12fbddf3f83d37547
 git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc-testing)
Signed-off-by: Marco Ballesio <balejs@google.com>
Signed-off-by: Li Li <dualli@google.com>
Acked-by: Todd Kjos <tkjos@google.com>
Link: https://lore.kernel.org/r/20210316011630.1121213-4-dualli@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Change-Id: Ie631f331ba4ca94a3bcdd43dec25fe9ba1306af2
  • Loading branch information
nadinsylaa authored and toddkjos committed Mar 24, 2021
1 parent efe13e4 commit 02fdd38
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
55 changes: 55 additions & 0 deletions drivers/android/binder.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,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)) {
Expand Down Expand Up @@ -4759,6 +4763,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;
Expand All @@ -4770,6 +4776,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);

Expand All @@ -4791,6 +4799,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;
Expand Down Expand Up @@ -4969,6 +5004,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;
Expand Down Expand Up @@ -5286,6 +5339,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))) {
Expand Down
6 changes: 6 additions & 0 deletions drivers/android/binder_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ struct binder_priority {
* @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)
Expand Down Expand Up @@ -443,6 +447,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;
Expand Down
7 changes: 7 additions & 0 deletions include/uapi/linux/android/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,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)
Expand All @@ -282,6 +288,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
Expand Down

0 comments on commit 02fdd38

Please sign in to comment.