binderfs: remove separate device_initcall()
[linux-2.6-microblaze.git] / drivers / android / binder.c
index 9f1000d..4d2b2ad 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/ratelimit.h>
 #include <linux/syscalls.h>
+#include <linux/task_work.h>
 
 #include <uapi/linux/android/binder.h>
 
 #include <asm/cacheflush.h>
 
 #include "binder_alloc.h"
+#include "binder_internal.h"
 #include "binder_trace.h"
 
 static HLIST_HEAD(binder_deferred_list);
@@ -94,22 +96,8 @@ static struct dentry *binder_debugfs_dir_entry_root;
 static struct dentry *binder_debugfs_dir_entry_proc;
 static atomic_t binder_last_id;
 
-#define BINDER_DEBUG_ENTRY(name) \
-static int binder_##name##_open(struct inode *inode, struct file *file) \
-{ \
-       return single_open(file, binder_##name##_show, inode->i_private); \
-} \
-\
-static const struct file_operations binder_##name##_fops = { \
-       .owner = THIS_MODULE, \
-       .open = binder_##name##_open, \
-       .read = seq_read, \
-       .llseek = seq_lseek, \
-       .release = single_release, \
-}
-
-static int binder_proc_show(struct seq_file *m, void *unused);
-BINDER_DEBUG_ENTRY(proc);
+static int proc_show(struct seq_file *m, void *unused);
+DEFINE_SHOW_ATTRIBUTE(proc);
 
 /* This is only defined in include/asm-arm/sizes.h */
 #ifndef SZ_1K
@@ -262,20 +250,6 @@ static struct binder_transaction_log_entry *binder_transaction_log_add(
        return e;
 }
 
-struct binder_context {
-       struct binder_node *binder_context_mgr_node;
-       struct mutex context_mgr_node_lock;
-
-       kuid_t binder_context_mgr_uid;
-       const char *name;
-};
-
-struct binder_device {
-       struct hlist_node hlist;
-       struct miscdevice miscdev;
-       struct binder_context context;
-};
-
 /**
  * struct binder_work - work enqueued on a worklist
  * @entry:             node enqueued on list
@@ -660,6 +634,7 @@ struct binder_transaction {
 #define binder_proc_lock(proc) _binder_proc_lock(proc, __LINE__)
 static void
 _binder_proc_lock(struct binder_proc *proc, int line)
+       __acquires(&proc->outer_lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
@@ -675,6 +650,7 @@ _binder_proc_lock(struct binder_proc *proc, int line)
 #define binder_proc_unlock(_proc) _binder_proc_unlock(_proc, __LINE__)
 static void
 _binder_proc_unlock(struct binder_proc *proc, int line)
+       __releases(&proc->outer_lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
@@ -690,6 +666,7 @@ _binder_proc_unlock(struct binder_proc *proc, int line)
 #define binder_inner_proc_lock(proc) _binder_inner_proc_lock(proc, __LINE__)
 static void
 _binder_inner_proc_lock(struct binder_proc *proc, int line)
+       __acquires(&proc->inner_lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
@@ -705,6 +682,7 @@ _binder_inner_proc_lock(struct binder_proc *proc, int line)
 #define binder_inner_proc_unlock(proc) _binder_inner_proc_unlock(proc, __LINE__)
 static void
 _binder_inner_proc_unlock(struct binder_proc *proc, int line)
+       __releases(&proc->inner_lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
@@ -720,6 +698,7 @@ _binder_inner_proc_unlock(struct binder_proc *proc, int line)
 #define binder_node_lock(node) _binder_node_lock(node, __LINE__)
 static void
 _binder_node_lock(struct binder_node *node, int line)
+       __acquires(&node->lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
@@ -735,6 +714,7 @@ _binder_node_lock(struct binder_node *node, int line)
 #define binder_node_unlock(node) _binder_node_unlock(node, __LINE__)
 static void
 _binder_node_unlock(struct binder_node *node, int line)
+       __releases(&node->lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
@@ -751,12 +731,16 @@ _binder_node_unlock(struct binder_node *node, int line)
 #define binder_node_inner_lock(node) _binder_node_inner_lock(node, __LINE__)
 static void
 _binder_node_inner_lock(struct binder_node *node, int line)
+       __acquires(&node->lock) __acquires(&node->proc->inner_lock)
 {
        binder_debug(BINDER_DEBUG_SPINLOCKS,
                     "%s: line=%d\n", __func__, line);
        spin_lock(&node->lock);
        if (node->proc)
                binder_inner_proc_lock(node->proc);
+       else
+               /* annotation for sparse */
+               __acquire(&node->proc->inner_lock);
 }
 
 /**
@@ -768,6 +752,7 @@ _binder_node_inner_lock(struct binder_node *node, int line)
 #define binder_node_inner_unlock(node) _binder_node_inner_unlock(node, __LINE__)
 static void
 _binder_node_inner_unlock(struct binder_node *node, int line)
+       __releases(&node->lock) __releases(&node->proc->inner_lock)
 {
        struct binder_proc *proc = node->proc;
 
@@ -775,6 +760,9 @@ _binder_node_inner_unlock(struct binder_node *node, int line)
                     "%s: line=%d\n", __func__, line);
        if (proc)
                binder_inner_proc_unlock(proc);
+       else
+               /* annotation for sparse */
+               __release(&node->proc->inner_lock);
        spin_unlock(&node->lock);
 }
 
@@ -1384,10 +1372,14 @@ static void binder_dec_node_tmpref(struct binder_node *node)
        binder_node_inner_lock(node);
        if (!node->proc)
                spin_lock(&binder_dead_nodes_lock);
+       else
+               __acquire(&binder_dead_nodes_lock);
        node->tmp_refs--;
        BUG_ON(node->tmp_refs < 0);
        if (!node->proc)
                spin_unlock(&binder_dead_nodes_lock);
+       else
+               __release(&binder_dead_nodes_lock);
        /*
         * Call binder_dec_node() to check if all refcounts are 0
         * and cleanup is needed. Calling with strong=0 and internal=1
@@ -1890,18 +1882,22 @@ static struct binder_thread *binder_get_txn_from(
  */
 static struct binder_thread *binder_get_txn_from_and_acq_inner(
                struct binder_transaction *t)
+       __acquires(&t->from->proc->inner_lock)
 {
        struct binder_thread *from;
 
        from = binder_get_txn_from(t);
-       if (!from)
+       if (!from) {
+               __acquire(&from->proc->inner_lock);
                return NULL;
+       }
        binder_inner_proc_lock(from->proc);
        if (t->from) {
                BUG_ON(from != t->from);
                return from;
        }
        binder_inner_proc_unlock(from->proc);
+       __acquire(&from->proc->inner_lock);
        binder_thread_dec_tmpref(from);
        return NULL;
 }
@@ -1973,6 +1969,8 @@ static void binder_send_failed_reply(struct binder_transaction *t,
                        binder_thread_dec_tmpref(target_thread);
                        binder_free_transaction(t);
                        return;
+               } else {
+                       __release(&target_thread->proc->inner_lock);
                }
                next = t->from_parent;
 
@@ -2160,6 +2158,64 @@ static bool binder_validate_fixup(struct binder_buffer *b,
        return (fixup_offset >= last_min_offset);
 }
 
+/**
+ * struct binder_task_work_cb - for deferred close
+ *
+ * @twork:                callback_head for task work
+ * @fd:                   fd to close
+ *
+ * Structure to pass task work to be handled after
+ * returning from binder_ioctl() via task_work_add().
+ */
+struct binder_task_work_cb {
+       struct callback_head twork;
+       struct file *file;
+};
+
+/**
+ * binder_do_fd_close() - close list of file descriptors
+ * @twork:     callback head for task work
+ *
+ * It is not safe to call ksys_close() during the binder_ioctl()
+ * function if there is a chance that binder's own file descriptor
+ * might be closed. This is to meet the requirements for using
+ * fdget() (see comments for __fget_light()). Therefore use
+ * task_work_add() to schedule the close operation once we have
+ * returned from binder_ioctl(). This function is a callback
+ * for that mechanism and does the actual ksys_close() on the
+ * given file descriptor.
+ */
+static void binder_do_fd_close(struct callback_head *twork)
+{
+       struct binder_task_work_cb *twcb = container_of(twork,
+                       struct binder_task_work_cb, twork);
+
+       fput(twcb->file);
+       kfree(twcb);
+}
+
+/**
+ * binder_deferred_fd_close() - schedule a close for the given file-descriptor
+ * @fd:                file-descriptor to close
+ *
+ * See comments in binder_do_fd_close(). This function is used to schedule
+ * a file-descriptor to be closed after returning from binder_ioctl().
+ */
+static void binder_deferred_fd_close(int fd)
+{
+       struct binder_task_work_cb *twcb;
+
+       twcb = kzalloc(sizeof(*twcb), GFP_KERNEL);
+       if (!twcb)
+               return;
+       init_task_work(&twcb->twork, binder_do_fd_close);
+       __close_fd_get_file(fd, &twcb->file);
+       if (twcb->file)
+               task_work_add(current, &twcb->twork, true);
+       else
+               kfree(twcb);
+}
+
 static void binder_transaction_buffer_release(struct binder_proc *proc,
                                              struct binder_buffer *buffer,
                                              binder_size_t *failed_at)
@@ -2299,7 +2355,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
                        }
                        fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
                        for (fd_index = 0; fd_index < fda->num_fds; fd_index++)
-                               ksys_close(fd_array[fd_index]);
+                               binder_deferred_fd_close(fd_array[fd_index]);
                } break;
                default:
                        pr_err("transaction release %d bad object type %x\n",
@@ -2394,11 +2450,15 @@ static int binder_translate_handle(struct flat_binder_object *fp,
                fp->cookie = node->cookie;
                if (node->proc)
                        binder_inner_proc_lock(node->proc);
+               else
+                       __acquire(&node->proc->inner_lock);
                binder_inc_node_nilocked(node,
                                         fp->hdr.type == BINDER_TYPE_BINDER,
                                         0, NULL);
                if (node->proc)
                        binder_inner_proc_unlock(node->proc);
+               else
+                       __release(&node->proc->inner_lock);
                trace_binder_transaction_ref_to_node(t, node, &src_rdata);
                binder_debug(BINDER_DEBUG_TRANSACTION,
                             "        ref %d desc %d -> node %d u%016llx\n",
@@ -2762,6 +2822,8 @@ static void binder_transaction(struct binder_proc *proc,
                binder_set_nice(in_reply_to->saved_priority);
                target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
                if (target_thread == NULL) {
+                       /* annotation for sparse */
+                       __release(&target_thread->proc->inner_lock);
                        return_error = BR_DEAD_REPLY;
                        return_error_line = __LINE__;
                        goto err_dead_binder;
@@ -3912,7 +3974,7 @@ static int binder_apply_fd_fixups(struct binder_transaction *t)
                } else if (ret) {
                        u32 *fdp = (u32 *)(t->buffer->data + fixup->offset);
 
-                       ksys_close(*fdp);
+                       binder_deferred_fd_close(*fdp);
                }
                list_del(&fixup->fixup_entry);
                kfree(fixup);
@@ -4164,6 +4226,11 @@ retry:
                        if (cmd == BR_DEAD_BINDER)
                                goto done; /* DEAD_BINDER notifications can cause transactions */
                } break;
+               default:
+                       binder_inner_proc_unlock(proc);
+                       pr_err("%d:%d: bad work type %d\n",
+                              proc->pid, thread->pid, w->type);
+                       break;
                }
 
                if (!t)
@@ -4467,6 +4534,8 @@ static int binder_thread_release(struct binder_proc *proc,
                spin_lock(&t->lock);
                if (t->to_thread == thread)
                        send_reply = t;
+       } else {
+               __acquire(&t->lock);
        }
        thread->is_dead = true;
 
@@ -4495,7 +4564,11 @@ static int binder_thread_release(struct binder_proc *proc,
                spin_unlock(&last_t->lock);
                if (t)
                        spin_lock(&t->lock);
+               else
+                       __acquire(&t->lock);
        }
+       /* annotation for sparse, lock not acquired in last iteration above */
+       __release(&t->lock);
 
        /*
         * If this thread used poll, make sure we remove the waitqueue
@@ -4938,8 +5011,12 @@ static int binder_open(struct inode *nodp, struct file *filp)
        proc->tsk = current->group_leader;
        INIT_LIST_HEAD(&proc->todo);
        proc->default_priority = task_nice(current);
-       binder_dev = container_of(filp->private_data, struct binder_device,
-                                 miscdev);
+       /* binderfs stashes devices in i_private */
+       if (is_binderfs_device(nodp))
+               binder_dev = nodp->i_private;
+       else
+               binder_dev = container_of(filp->private_data,
+                                         struct binder_device, miscdev);
        proc->context = &binder_dev->context;
        binder_alloc_init(&proc->alloc);
 
@@ -4967,7 +5044,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
                proc->debugfs_entry = debugfs_create_file(strbuf, 0444,
                        binder_debugfs_dir_entry_proc,
                        (void *)(unsigned long)proc->pid,
-                       &binder_proc_fops);
+                       &proc_fops);
        }
 
        return 0;
@@ -5391,6 +5468,9 @@ static void print_binder_proc(struct seq_file *m,
        for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) {
                struct binder_node *node = rb_entry(n, struct binder_node,
                                                    rb_node);
+               if (!print_all && !node->has_async_transaction)
+                       continue;
+
                /*
                 * take a temporary reference on the node so it
                 * survives and isn't removed from the tree
@@ -5595,7 +5675,7 @@ static void print_binder_proc_stats(struct seq_file *m,
 }
 
 
-static int binder_state_show(struct seq_file *m, void *unused)
+static int state_show(struct seq_file *m, void *unused)
 {
        struct binder_proc *proc;
        struct binder_node *node;
@@ -5634,7 +5714,7 @@ static int binder_state_show(struct seq_file *m, void *unused)
        return 0;
 }
 
-static int binder_stats_show(struct seq_file *m, void *unused)
+static int stats_show(struct seq_file *m, void *unused)
 {
        struct binder_proc *proc;
 
@@ -5650,7 +5730,7 @@ static int binder_stats_show(struct seq_file *m, void *unused)
        return 0;
 }
 
-static int binder_transactions_show(struct seq_file *m, void *unused)
+static int transactions_show(struct seq_file *m, void *unused)
 {
        struct binder_proc *proc;
 
@@ -5663,7 +5743,7 @@ static int binder_transactions_show(struct seq_file *m, void *unused)
        return 0;
 }
 
-static int binder_proc_show(struct seq_file *m, void *unused)
+static int proc_show(struct seq_file *m, void *unused)
 {
        struct binder_proc *itr;
        int pid = (unsigned long)m->private;
@@ -5706,7 +5786,7 @@ static void print_binder_transaction_log_entry(struct seq_file *m,
                        "\n" : " (incomplete)\n");
 }
 
-static int binder_transaction_log_show(struct seq_file *m, void *unused)
+static int transaction_log_show(struct seq_file *m, void *unused)
 {
        struct binder_transaction_log *log = m->private;
        unsigned int log_cur = atomic_read(&log->cur);
@@ -5727,7 +5807,7 @@ static int binder_transaction_log_show(struct seq_file *m, void *unused)
        return 0;
 }
 
-static const struct file_operations binder_fops = {
+const struct file_operations binder_fops = {
        .owner = THIS_MODULE,
        .poll = binder_poll,
        .unlocked_ioctl = binder_ioctl,
@@ -5738,10 +5818,10 @@ static const struct file_operations binder_fops = {
        .release = binder_release,
 };
 
-BINDER_DEBUG_ENTRY(state);
-BINDER_DEBUG_ENTRY(stats);
-BINDER_DEBUG_ENTRY(transactions);
-BINDER_DEBUG_ENTRY(transaction_log);
+DEFINE_SHOW_ATTRIBUTE(state);
+DEFINE_SHOW_ATTRIBUTE(stats);
+DEFINE_SHOW_ATTRIBUTE(transactions);
+DEFINE_SHOW_ATTRIBUTE(transaction_log);
 
 static int __init init_binder_device(const char *name)
 {
@@ -5774,9 +5854,10 @@ static int __init init_binder_device(const char *name)
 static int __init binder_init(void)
 {
        int ret;
-       char *device_name, *device_names, *device_tmp;
+       char *device_name, *device_tmp;
        struct binder_device *device;
        struct hlist_node *tmp;
+       char *device_names = NULL;
 
        ret = binder_alloc_shrinker_init();
        if (ret)
@@ -5795,46 +5876,52 @@ static int __init binder_init(void)
                                    0444,
                                    binder_debugfs_dir_entry_root,
                                    NULL,
-                                   &binder_state_fops);
+                                   &state_fops);
                debugfs_create_file("stats",
                                    0444,
                                    binder_debugfs_dir_entry_root,
                                    NULL,
-                                   &binder_stats_fops);
+                                   &stats_fops);
                debugfs_create_file("transactions",
                                    0444,
                                    binder_debugfs_dir_entry_root,
                                    NULL,
-                                   &binder_transactions_fops);
+                                   &transactions_fops);
                debugfs_create_file("transaction_log",
                                    0444,
                                    binder_debugfs_dir_entry_root,
                                    &binder_transaction_log,
-                                   &binder_transaction_log_fops);
+                                   &transaction_log_fops);
                debugfs_create_file("failed_transaction_log",
                                    0444,
                                    binder_debugfs_dir_entry_root,
                                    &binder_transaction_log_failed,
-                                   &binder_transaction_log_fops);
+                                   &transaction_log_fops);
        }
 
-       /*
-        * Copy the module_parameter string, because we don't want to
-        * tokenize it in-place.
-        */
-       device_names = kstrdup(binder_devices_param, GFP_KERNEL);
-       if (!device_names) {
-               ret = -ENOMEM;
-               goto err_alloc_device_names_failed;
-       }
+       if (strcmp(binder_devices_param, "") != 0) {
+               /*
+               * Copy the module_parameter string, because we don't want to
+               * tokenize it in-place.
+                */
+               device_names = kstrdup(binder_devices_param, GFP_KERNEL);
+               if (!device_names) {
+                       ret = -ENOMEM;
+                       goto err_alloc_device_names_failed;
+               }
 
-       device_tmp = device_names;
-       while ((device_name = strsep(&device_tmp, ","))) {
-               ret = init_binder_device(device_name);
-               if (ret)
-                       goto err_init_binder_device_failed;
+               device_tmp = device_names;
+               while ((device_name = strsep(&device_tmp, ","))) {
+                       ret = init_binder_device(device_name);
+                       if (ret)
+                               goto err_init_binder_device_failed;
+               }
        }
 
+       ret = init_binderfs();
+       if (ret)
+               goto err_init_binder_device_failed;
+
        return ret;
 
 err_init_binder_device_failed: