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:
committed by
Thierry Strudel
parent
f120798fab
commit
e04d752ca7
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user