--- drivers/staging/android/binder.c +++ drivers/staging/android/binder.c @@ -34,6 +34,8 @@ #include #include +#include + #include "binder.h" static DEFINE_MUTEX(binder_lock); @@ -49,6 +51,8 @@ static struct dentry *binder_debugfs_dir_entry_proc; static struct binder_node *binder_context_mgr_node; static uid_t binder_context_mgr_uid = -1; static int binder_last_id; +static struct task_struct *binder_deferred_task; +static DECLARE_WAIT_QUEUE_HEAD(binder_deferred_wq); static struct workqueue_struct *binder_deferred_workqueue; #define BINDER_DEBUG_ENTRY(name) \ @@ -3075,14 +3079,23 @@ static void binder_deferred_release(struct binder_proc *proc) kfree(proc); } -static void binder_deferred_func(struct work_struct *work) +static int binder_deferred_thread(void *ignore) { struct binder_proc *proc; struct files_struct *files; - + int ret; int defer; - do { + + for (;;) { + + do { + ret = wait_event_interruptible(binder_deferred_wq, !hlist_empty(&binder_deferred_list)); + } while (ret == -ERESTARTSYS); + if (kthread_should_stop()) + break; + mutex_lock(&binder_lock); + mutex_lock(&binder_deferred_lock); if (!hlist_empty(&binder_deferred_list)) { proc = hlist_entry(binder_deferred_list.first, @@ -3097,24 +3110,27 @@ static void binder_deferred_func(struct work_struct *work) mutex_unlock(&binder_deferred_lock); files = NULL; - if (defer & BINDER_DEFERRED_PUT_FILES) { - files = proc->files; - if (files) - proc->files = NULL; - } + if (proc != NULL) { - if (defer & BINDER_DEFERRED_FLUSH) - binder_deferred_flush(proc); + if (defer & BINDER_DEFERRED_PUT_FILES) { + files = proc->files; + if (files) + proc->files = NULL; + } - if (defer & BINDER_DEFERRED_RELEASE) - binder_deferred_release(proc); /* frees proc */ + if (defer & BINDER_DEFERRED_FLUSH) + binder_deferred_flush(proc); + + if (defer & BINDER_DEFERRED_RELEASE) + binder_deferred_release(proc); /* frees proc */ + } mutex_unlock(&binder_lock); if (files) put_files_struct(files); - } while (proc); + } + return 0; } -static DECLARE_WORK(binder_deferred_work, binder_deferred_func); static void binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) @@ -3124,9 +3140,9 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) if (hlist_unhashed(&proc->deferred_work_node)) { hlist_add_head(&proc->deferred_work_node, &binder_deferred_list); - queue_work(binder_deferred_workqueue, &binder_deferred_work); } mutex_unlock(&binder_deferred_lock); + wake_up_interruptible(&binder_deferred_wq); } static void print_binder_transaction(struct seq_file *m, const char *prefix, @@ -3603,6 +3619,12 @@ static int __init binder_init(void) &binder_transaction_log_failed, &binder_transaction_log_fops); } + + if (ret == 0) { + binder_deferred_task = kthread_run(binder_deferred_thread, NULL, "binder_deferred_thread"); + if (binder_deferred_task == NULL) + ret = PTR_ERR(binder_deferred_task); + } return ret; }