binder: remove global binder lock

Remove global mutex and rely on fine-grained locking

Bug: 33250092 32225111
Change-Id: Idd1ae2e52d654e5dd76d443a1ff97522e687fd4c
Signed-off-by: Todd Kjos <tkjos@google.com>
This commit is contained in:
Todd Kjos
2016-11-14 11:37:41 -08:00
committed by Thierry Strudel
parent f120798fab
commit e04d752ca7
2 changed files with 2 additions and 92 deletions

View File

@@ -46,8 +46,6 @@
#include "binder_alloc.h"
#include "binder_trace.h"
static DEFINE_MUTEX(binder_main_lock);
static HLIST_HEAD(binder_deferred_list);
static DEFINE_MUTEX(binder_deferred_lock);
@@ -117,9 +115,6 @@ static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
static bool binder_debug_no_lock;
module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
module_param_named(devices, binder_devices_param, charp, S_IRUGO);
@@ -594,19 +589,6 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
return retval;
}
static inline void binder_lock(const char *tag)
{
trace_binder_lock(tag);
mutex_lock(&binder_main_lock);
trace_binder_locked(tag);
}
static inline void binder_unlock(const char *tag)
{
trace_binder_unlock(tag);
mutex_unlock(&binder_main_lock);
}
static void binder_set_nice(long nice)
{
long min_nice;
@@ -1938,11 +1920,9 @@ static void binder_transaction(struct binder_proc *proc,
trace_binder_transaction(reply, t, target_node);
binder_unlock(__func__);
t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
tr->offsets_size, extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
binder_lock(__func__);
if (t->buffer == NULL) {
return_error = !(target_proc->tsk->flags & PF_EXITING) ?
BR_FAILED_REPLY : BR_DEAD_REPLY;
@@ -2184,9 +2164,7 @@ err_copy_data_failed:
trace_binder_transaction_failed_buffer_release(t->buffer);
binder_transaction_buffer_release(target_proc, t->buffer, offp);
t->buffer->transaction = NULL;
binder_unlock(__func__);
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
binder_lock(__func__);
err_binder_alloc_buf_failed:
kfree(tcomplete);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
@@ -2384,10 +2362,8 @@ static int binder_thread_write(struct binder_proc *proc,
return -EFAULT;
ptr += sizeof(binder_uintptr_t);
binder_unlock(__func__);
buffer = binder_alloc_buffer_lookup(&proc->alloc,
data_ptr);
binder_lock(__func__);
if (buffer == NULL) {
binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n",
proc->pid, thread->pid, (u64)data_ptr);
@@ -2432,9 +2408,7 @@ static int binder_thread_write(struct binder_proc *proc,
}
trace_binder_transaction_buffer_release(buffer);
binder_transaction_buffer_release(proc, buffer, NULL);
binder_unlock(__func__);
binder_alloc_free_buf(&proc->alloc, buffer);
binder_lock(__func__);
break;
}
@@ -2753,8 +2727,6 @@ retry:
wake_up_interruptible(&proc->wait);
}
binder_unlock(__func__);
trace_binder_wait_for_work(wait_for_proc_work,
!!thread->transaction_stack,
!binder_worklist_empty(&thread->todo));
@@ -2766,16 +2738,13 @@ retry:
BINDER_LOOPER_STATE_ENTERED)));
binder_set_nice(proc->default_priority);
if (non_block) {
if (!binder_has_proc_work(proc, thread)) {
binder_lock(__func__);
if (!binder_has_proc_work(proc, thread))
ret = -EAGAIN;
}
} else {
WRITE_ONCE(thread->waiting_for_proc_work, true);
binder_put_thread(thread);
ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
*threadp = thread = binder_get_thread(proc);
binder_lock(__func__);
if (thread)
WRITE_ONCE(thread->waiting_for_proc_work,
false);
@@ -2784,9 +2753,8 @@ retry:
}
} else {
if (non_block) {
if (!binder_has_thread_work(thread)) {
if (!binder_has_thread_work(thread))
ret = -EAGAIN;
}
} else {
binder_put_thread(thread);
ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
@@ -2796,8 +2764,6 @@ retry:
}
}
binder_lock(__func__);
if (wait_for_proc_work)
atomic_dec(&proc->ready_threads);
@@ -3406,8 +3372,6 @@ static unsigned int binder_poll(struct file *filp,
struct binder_thread *thread = NULL;
int wait_for_proc_work;
binder_lock(__func__);
thread = binder_get_thread(proc);
binder_proc_lock(thread->proc, __LINE__);
@@ -3416,8 +3380,6 @@ static unsigned int binder_poll(struct file *filp,
thread->return_error == BR_OK;
binder_proc_unlock(thread->proc, __LINE__);
binder_unlock(__func__);
if (wait_for_proc_work) {
if (binder_has_proc_work(proc, thread))
goto ret_pollin;
@@ -3596,7 +3558,6 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (ret)
goto err_wait_event;
binder_lock(__func__);
thread = binder_get_thread(proc);
if (thread == NULL) {
ret = -ENOMEM;
@@ -3662,7 +3623,6 @@ err:
zombie_cleanup_check(proc);
binder_put_thread(thread);
}
binder_unlock(__func__);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret != -ERESTARTSYS)
pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
@@ -4169,7 +4129,6 @@ static void binder_deferred_func(struct work_struct *work)
int defer;
do {
binder_lock(__func__);
mutex_lock(&binder_deferred_lock);
if (!hlist_empty(&binder_deferred_list)) {
proc = hlist_entry(binder_deferred_list.first,
@@ -4202,10 +4161,7 @@ static void binder_deferred_func(struct work_struct *work)
if (defer & BINDER_ZOMBIE_CLEANUP)
binder_clear_zombies();
binder_unlock(__func__);
} while (proc);
}
static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
@@ -4598,10 +4554,6 @@ static void print_binder_proc_stats(struct seq_file *m,
static int binder_state_show(struct seq_file *m, void *unused)
{
struct binder_proc *proc;
int do_lock = !binder_debug_no_lock;
if (do_lock)
binder_lock(__func__);
seq_puts(m, "binder state:\n");
@@ -4609,22 +4561,15 @@ static int binder_state_show(struct seq_file *m, void *unused)
hlist_for_each_entry(proc, &binder_procs, proc_node)
print_binder_proc(m, proc, 1);
mutex_unlock(&binder_procs_lock);
if (do_lock)
binder_unlock(__func__);
return 0;
}
static int binder_stats_show(struct seq_file *m, void *unused)
{
struct binder_proc *proc;
int do_lock = !binder_debug_no_lock;
int proc_count = 0;
int i, sum = 0, maxactive = 0;
if (do_lock)
binder_lock(__func__);
seq_puts(m, "binder stats:\n");
print_binder_stats(m, "", &binder_stats);
@@ -4635,8 +4580,6 @@ static int binder_stats_show(struct seq_file *m, void *unused)
print_binder_proc_stats(m, proc);
}
mutex_unlock(&binder_procs_lock);
if (do_lock)
binder_unlock(__func__);
for (i = 0; i < SEQ_BUCKETS; i++) {
sum += binder_active_threads[i].active_count;
@@ -4658,18 +4601,12 @@ static int binder_stats_show(struct seq_file *m, void *unused)
static int binder_transactions_show(struct seq_file *m, void *unused)
{
struct binder_proc *proc;
int do_lock = !binder_debug_no_lock;
if (do_lock)
binder_lock(__func__);
seq_puts(m, "binder transactions:\n");
mutex_lock(&binder_procs_lock);
hlist_for_each_entry(proc, &binder_procs, proc_node)
print_binder_proc(m, proc, 0);
mutex_unlock(&binder_procs_lock);
if (do_lock)
binder_unlock(__func__);
return 0;
}
@@ -4677,10 +4614,6 @@ static int binder_proc_show(struct seq_file *m, void *unused)
{
struct binder_proc *itr;
int pid = (unsigned long)m->private;
int do_lock = !binder_debug_no_lock;
if (do_lock)
binder_lock(__func__);
mutex_lock(&binder_procs_lock);
hlist_for_each_entry(itr, &binder_procs, proc_node) {
@@ -4691,8 +4624,6 @@ static int binder_proc_show(struct seq_file *m, void *unused)
}
mutex_unlock(&binder_procs_lock);
if (do_lock)
binder_unlock(__func__);
return 0;
}

View File

@@ -42,27 +42,6 @@ TRACE_EVENT(binder_ioctl,
TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
);
DECLARE_EVENT_CLASS(binder_lock_class,
TP_PROTO(const char *tag),
TP_ARGS(tag),
TP_STRUCT__entry(
__field(const char *, tag)
),
TP_fast_assign(
__entry->tag = tag;
),
TP_printk("tag=%s", __entry->tag)
);
#define DEFINE_BINDER_LOCK_EVENT(name) \
DEFINE_EVENT(binder_lock_class, name, \
TP_PROTO(const char *func), \
TP_ARGS(func))
DEFINE_BINDER_LOCK_EVENT(binder_lock);
DEFINE_BINDER_LOCK_EVENT(binder_locked);
DEFINE_BINDER_LOCK_EVENT(binder_unlock);
DECLARE_EVENT_CLASS(binder_function_return_class,
TP_PROTO(int ret),
TP_ARGS(ret),