On Fri, Sep 7, 2018 at 6:38 AM Martijn Coenen <maco@xxxxxxxxxxx> wrote: > > 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@xxxxxxxxxxx> > --- > v2: made sure reserved fields are aligned, and enforce caller zeroes > all fields except handle, as suggested by Dan Carpenter. > > drivers/android/binder.c | 55 +++++++++++++++++++++++++++++ > include/uapi/linux/android/binder.h | 10 ++++++ > 2 files changed, 65 insertions(+) > > diff --git a/drivers/android/binder.c b/drivers/android/binder.c > index d58763b6b0090..5b25412e15ccf 100644 > --- a/drivers/android/binder.c > +++ b/drivers/android/binder.c > @@ -4544,6 +4544,42 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) > 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; Aren't we under-reporting the weak refs here? The "internal weak" refs are the count of elements in node->refs, so we need to add something like: hlist_for_each_entry(ref, &node->refs, node_entry) info->weak_count++; > + > + binder_put_node(node); > + > + return 0; > +} > + > static int binder_ioctl_get_node_debug_info(struct binder_proc *proc, > struct binder_node_debug_info *info) > { > @@ -4638,6 +4674,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; > > diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h > index bfaec6903b8bc..b9ba520f7e4bb 100644 > --- a/include/uapi/linux/android/binder.h > +++ b/include/uapi/linux/android/binder.h > @@ -200,6 +200,15 @@ struct binder_node_debug_info { > __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_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) > #define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32) > @@ -208,6 +217,7 @@ struct binder_node_debug_info { > #define BINDER_THREAD_EXIT _IOW('b', 8, __s32) > #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_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref) > > /* > * NOTE: Two special error codes you should check for when calling > -- > 2.19.0.rc2.392.g5ba43deb5a-goog > _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel