Commit b7e6a896 authored by Martijn Coenen's avatar Martijn Coenen Committed by Greg Kroah-Hartman

binder: Add BINDER_GET_NODE_INFO_FOR_REF ioctl.

This allows the context manager to retrieve information about nodes
that it holds a reference to, such as the current number of
references to those nodes.

Such information can for example be used to determine whether the
servicemanager is the only process holding a reference to a node.
This information can then be passed on to the process holding the
node, which can in turn decide whether it wants to shut down to
reduce resource usage.
Signed-off-by: default avatarMartijn Coenen <maco@android.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6b6642da
...@@ -4661,6 +4661,42 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) ...@@ -4661,6 +4661,42 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
return ret; return ret;
} }
static int binder_ioctl_get_node_info_for_ref(struct binder_proc *proc,
struct binder_node_info_for_ref *info)
{
struct binder_node *node;
struct binder_context *context = proc->context;
__u32 handle = info->handle;
if (info->strong_count || info->weak_count || info->reserved1 ||
info->reserved2 || info->reserved3) {
binder_user_error("%d BINDER_GET_NODE_INFO_FOR_REF: only handle may be non-zero.",
proc->pid);
return -EINVAL;
}
/* This ioctl may only be used by the context manager */
mutex_lock(&context->context_mgr_node_lock);
if (!context->binder_context_mgr_node ||
context->binder_context_mgr_node->proc != proc) {
mutex_unlock(&context->context_mgr_node_lock);
return -EPERM;
}
mutex_unlock(&context->context_mgr_node_lock);
node = binder_get_node_from_ref(proc, handle, true, NULL);
if (!node)
return -EINVAL;
info->strong_count = node->local_strong_refs +
node->internal_strong_refs;
info->weak_count = node->local_weak_refs;
binder_put_node(node);
return 0;
}
static int binder_ioctl_get_node_debug_info(struct binder_proc *proc, static int binder_ioctl_get_node_debug_info(struct binder_proc *proc,
struct binder_node_debug_info *info) struct binder_node_debug_info *info)
{ {
...@@ -4755,6 +4791,25 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -4755,6 +4791,25 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
} }
break; break;
} }
case BINDER_GET_NODE_INFO_FOR_REF: {
struct binder_node_info_for_ref info;
if (copy_from_user(&info, ubuf, sizeof(info))) {
ret = -EFAULT;
goto err;
}
ret = binder_ioctl_get_node_info_for_ref(proc, &info);
if (ret < 0)
goto err;
if (copy_to_user(ubuf, &info, sizeof(info))) {
ret = -EFAULT;
goto err;
}
break;
}
case BINDER_GET_NODE_DEBUG_INFO: { case BINDER_GET_NODE_DEBUG_INFO: {
struct binder_node_debug_info info; struct binder_node_debug_info info;
......
...@@ -200,6 +200,15 @@ struct binder_node_debug_info { ...@@ -200,6 +200,15 @@ struct binder_node_debug_info {
__u32 has_weak_ref; __u32 has_weak_ref;
}; };
struct binder_node_info_for_ref {
__u32 handle;
__u32 strong_count;
__u32 weak_count;
__u32 reserved1;
__u32 reserved2;
__u32 reserved3;
};
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) #define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32) #define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
...@@ -208,6 +217,7 @@ struct binder_node_debug_info { ...@@ -208,6 +217,7 @@ struct binder_node_debug_info {
#define BINDER_THREAD_EXIT _IOW('b', 8, __s32) #define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
#define BINDER_VERSION _IOWR('b', 9, struct binder_version) #define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info) #define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
/* /*
* NOTE: Two special error codes you should check for when calling * NOTE: Two special error codes you should check for when calling
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment