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: Martijn Coenen <maco@android.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
6b6642dadd
commit
b7e6a8961b
@@ -4661,6 +4661,42 @@ out:
|
||||
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,
|
||||
struct binder_node_debug_info *info)
|
||||
{
|
||||
@@ -4755,6 +4791,25 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
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: {
|
||||
struct binder_node_debug_info info;
|
||||
|
||||
|
Reference in New Issue
Block a user