diff options
Diffstat (limited to 'drivers/staging/android')
-rw-r--r-- | drivers/staging/android/binder.c | 713 | ||||
-rw-r--r-- | drivers/staging/android/lowmemorykiller.c | 41 | ||||
-rw-r--r-- | drivers/staging/android/lowmemorykiller.txt | 16 |
3 files changed, 403 insertions, 367 deletions
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 17d89a8..99010d4 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -31,18 +31,21 @@ #include <linux/sched.h> #include <linux/uaccess.h> #include <linux/vmalloc.h> + #include "binder.h" static DEFINE_MUTEX(binder_lock); +static DEFINE_MUTEX(binder_deferred_lock); + static HLIST_HEAD(binder_procs); +static HLIST_HEAD(binder_deferred_list); +static HLIST_HEAD(binder_dead_nodes); + +static struct proc_dir_entry *binder_proc_dir_entry_root; +static struct proc_dir_entry *binder_proc_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 proc_dir_entry *binder_proc_dir_entry_root; -static struct proc_dir_entry *binder_proc_dir_entry_proc; -static struct hlist_head binder_dead_nodes; -static HLIST_HEAD(binder_deferred_list); -static DEFINE_MUTEX(binder_deferred_lock); static int binder_read_proc_proc(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -100,6 +103,12 @@ static int binder_set_stop_on_user_error(const char *val, module_param_call(stop_on_user_error, binder_set_stop_on_user_error, param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); +#define binder_debug(mask, x...) \ + do { \ + if (binder_debug_mask & mask) \ + printk(KERN_INFO x); \ + } while (0) + #define binder_user_error(x...) \ do { \ if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \ @@ -108,7 +117,7 @@ module_param_call(stop_on_user_error, binder_set_stop_on_user_error, binder_stop_on_user_error = 2; \ } while (0) -enum { +enum binder_stat_types { BINDER_STAT_PROC, BINDER_STAT_THREAD, BINDER_STAT_NODE, @@ -128,6 +137,16 @@ struct binder_stats { static struct binder_stats binder_stats; +static inline void binder_stats_deleted(enum binder_stat_types type) +{ + binder_stats.obj_deleted[type]++; +} + +static inline void binder_stats_created(enum binder_stat_types type) +{ + binder_stats.obj_created[type]++; +} + struct binder_transaction_log_entry { int debug_id; int call_type; @@ -145,8 +164,8 @@ struct binder_transaction_log { int full; struct binder_transaction_log_entry entry[32]; }; -struct binder_transaction_log binder_transaction_log; -struct binder_transaction_log binder_transaction_log_failed; +static struct binder_transaction_log binder_transaction_log; +static struct binder_transaction_log binder_transaction_log_failed; static struct binder_transaction_log_entry *binder_transaction_log_add( struct binder_transaction_log *log) @@ -237,7 +256,7 @@ struct binder_buffer { uint8_t data[0]; }; -enum { +enum binder_deferred_state { BINDER_DEFERRED_PUT_FILES = 0x01, BINDER_DEFERRED_FLUSH = 0x02, BINDER_DEFERRED_RELEASE = 0x04, @@ -320,7 +339,8 @@ struct binder_transaction { uid_t sender_euid; }; -static void binder_defer_work(struct binder_proc *proc, int defer); +static void +binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); /* * copied from get_unused_fd_flags @@ -468,9 +488,9 @@ static void binder_set_nice(long nice) return; } min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur; - if (binder_debug_mask & BINDER_DEBUG_PRIORITY_CAP) - printk(KERN_INFO "binder: %d: nice value %ld not allowed use " - "%ld instead\n", current->pid, nice, min_nice); + binder_debug(BINDER_DEBUG_PRIORITY_CAP, + "binder: %d: nice value %ld not allowed use " + "%ld instead\n", current->pid, nice, min_nice); set_user_nice(current, min_nice); if (min_nice < 20) return; @@ -500,9 +520,9 @@ static void binder_insert_free_buffer(struct binder_proc *proc, new_buffer_size = binder_buffer_size(proc, new_buffer); - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: add free buffer, size %zd, " - "at %p\n", proc->pid, new_buffer_size, new_buffer); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: add free buffer, size %zd, " + "at %p\n", proc->pid, new_buffer_size, new_buffer); while (*p) { parent = *p; @@ -579,9 +599,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, struct page **page; struct mm_struct *mm; - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: %s pages %p-%p\n", - proc->pid, allocate ? "allocate" : "free", start, end); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: %s pages %p-%p\n", proc->pid, + allocate ? "allocate" : "free", start, end); if (end <= start) return 0; @@ -696,10 +716,9 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, if (is_async && proc->free_async_space < size + sizeof(struct binder_buffer)) { - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_ERR - "binder: %d: binder_alloc_buf size %zd failed, " - "no async space left\n", proc->pid, size); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: binder_alloc_buf size %zd" + "failed, no async space left\n", proc->pid, size); return NULL; } @@ -727,9 +746,10 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, buffer = rb_entry(best_fit, struct binder_buffer, rb_node); buffer_size = binder_buffer_size(proc, buffer); } - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd got buff" - "er %p size %zd\n", proc->pid, size, buffer, buffer_size); + + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: binder_alloc_buf size %zd got buff" + "er %p size %zd\n", proc->pid, size, buffer, buffer_size); has_page_addr = (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); @@ -756,18 +776,18 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, new_buffer->free = 1; binder_insert_free_buffer(proc, new_buffer); } - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd got " - "%p\n", proc->pid, size, buffer); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: binder_alloc_buf size %zd got " + "%p\n", proc->pid, size, buffer); buffer->data_size = data_size; buffer->offsets_size = offsets_size; buffer->async_transaction = is_async; if (is_async) { proc->free_async_space -= size + sizeof(struct binder_buffer); - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC_ASYNC) - printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, + "binder: %d: binder_alloc_buf size %zd " + "async free %zd\n", proc->pid, size, + proc->free_async_space); } return buffer; @@ -797,9 +817,9 @@ static void binder_delete_free_buffer(struct binder_proc *proc, free_page_start = 0; if (buffer_end_page(prev) == buffer_end_page(buffer)) free_page_end = 0; - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: merge free, buffer %p " - "share page with %p\n", proc->pid, buffer, prev); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: merge free, buffer %p " + "share page with %p\n", proc->pid, buffer, prev); } if (!list_is_last(&buffer->entry, &proc->buffers)) { @@ -810,19 +830,19 @@ static void binder_delete_free_buffer(struct binder_proc *proc, if (buffer_start_page(next) == buffer_start_page(buffer)) free_page_start = 0; - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: merge free, " - "buffer %p share page with %p\n", - proc->pid, buffer, prev); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: merge free, buffer" + " %p share page with %p\n", proc->pid, + buffer, prev); } } list_del(&buffer->entry); if (free_page_start || free_page_end) { - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: merge free, buffer %p do " - "not share page%s%s with with %p or %p\n", - proc->pid, buffer, free_page_start ? "" : " end", - free_page_end ? "" : " start", prev, next); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: merge free, buffer %p do " + "not share page%s%s with with %p or %p\n", + proc->pid, buffer, free_page_start ? "" : " end", + free_page_end ? "" : " start", prev, next); binder_update_page_range(proc, 0, free_page_start ? buffer_start_page(buffer) : buffer_end_page(buffer), (free_page_end ? buffer_end_page(buffer) : @@ -839,9 +859,10 @@ static void binder_free_buf(struct binder_proc *proc, size = ALIGN(buffer->data_size, sizeof(void *)) + ALIGN(buffer->offsets_size, sizeof(void *)); - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO "binder: %d: binder_free_buf %p size %zd buffer" - "_size %zd\n", proc->pid, buffer, size, buffer_size); + + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder: %d: binder_free_buf %p size %zd buffer" + "_size %zd\n", proc->pid, buffer, size, buffer_size); BUG_ON(buffer->free); BUG_ON(size > buffer_size); @@ -851,10 +872,11 @@ static void binder_free_buf(struct binder_proc *proc, if (buffer->async_transaction) { proc->free_async_space += size + sizeof(struct binder_buffer); - if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC_ASYNC) - printk(KERN_INFO "binder: %d: binder_free_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); + + binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, + "binder: %d: binder_free_buf size %zd " + "async free %zd\n", proc->pid, size, + proc->free_async_space); } binder_update_page_range(proc, 0, @@ -925,7 +947,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, node = kzalloc(sizeof(*node), GFP_KERNEL); if (node == NULL) return NULL; - binder_stats.obj_created[BINDER_STAT_NODE]++; + binder_stats_created(BINDER_STAT_NODE); rb_link_node(&node->rb_node, parent, p); rb_insert_color(&node->rb_node, &proc->nodes); node->debug_id = ++binder_last_id; @@ -935,10 +957,10 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, node->work.type = BINDER_WORK_NODE; INIT_LIST_HEAD(&node->work.entry); INIT_LIST_HEAD(&node->async_todo); - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: %d:%d node %d u%p c%p created\n", - proc->pid, current->pid, node->debug_id, - node->ptr, node->cookie); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: %d:%d node %d u%p c%p created\n", + proc->pid, current->pid, node->debug_id, + node->ptr, node->cookie); return node; } @@ -1003,15 +1025,17 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal) list_del_init(&node->work.entry); if (node->proc) { rb_erase(&node->rb_node, &node->proc->nodes); - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: refless node %d deleted\n", node->debug_id); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: refless node %d deleted\n", + node->debug_id); } else { hlist_del(&node->dead_node); - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: dead node %d deleted\n", node->debug_id); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: dead node %d deleted\n", + node->debug_id); } kfree(node); - binder_stats.obj_deleted[BINDER_STAT_NODE]++; + binder_stats_deleted(BINDER_STAT_NODE); } } @@ -1060,7 +1084,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); if (new_ref == NULL) return NULL; - binder_stats.obj_created[BINDER_STAT_REF]++; + binder_stats_created(BINDER_STAT_REF); new_ref->debug_id = ++binder_last_id; new_ref->proc = proc; new_ref->node = node; @@ -1091,25 +1115,27 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); if (node) { hlist_add_head(&new_ref->node_entry, &node->refs); - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: %d new ref %d desc %d for " - "node %d\n", proc->pid, new_ref->debug_id, - new_ref->desc, node->debug_id); + + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: %d new ref %d desc %d for " + "node %d\n", proc->pid, new_ref->debug_id, + new_ref->desc, node->debug_id); } else { - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: %d new ref %d desc %d for " - "dead node\n", proc->pid, new_ref->debug_id, - new_ref->desc); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: %d new ref %d desc %d for " + "dead node\n", proc->pid, new_ref->debug_id, + new_ref->desc); } return new_ref; } static void binder_delete_ref(struct binder_ref *ref) { - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: %d delete ref %d desc %d for " - "node %d\n", ref->proc->pid, ref->debug_id, - ref->desc, ref->node->debug_id); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: %d delete ref %d desc %d for " + "node %d\n", ref->proc->pid, ref->debug_id, + ref->desc, ref->node->debug_id); + rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); if (ref->strong) @@ -1117,16 +1143,16 @@ static void binder_delete_ref(struct binder_ref *ref) hlist_del(&ref->node_entry); binder_dec_node(ref->node, 0, 1); if (ref->death) { - if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) - printk(KERN_INFO "binder: %d delete ref %d desc %d " - "has death notification\n", ref->proc->pid, - ref->debug_id, ref->desc); + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "binder: %d delete ref %d desc %d " + "has death notification\n", ref->proc->pid, + ref->debug_id, ref->desc); list_del(&ref->death->work.entry); kfree(ref->death); - binder_stats.obj_deleted[BINDER_STAT_DEATH]++; + binder_stats_deleted(BINDER_STAT_DEATH); } kfree(ref); - binder_stats.obj_deleted[BINDER_STAT_REF]++; + binder_stats_deleted(BINDER_STAT_REF); } static int binder_inc_ref(struct binder_ref *ref, int strong, @@ -1198,7 +1224,7 @@ static void binder_pop_transaction(struct binder_thread *target_thread, if (t->buffer) t->buffer->transaction = NULL; kfree(t); - binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++; + binder_stats_deleted(BINDER_STAT_TRANSACTION); } static void binder_send_failed_reply(struct binder_transaction *t, @@ -1216,9 +1242,11 @@ static void binder_send_failed_reply(struct binder_transaction *t, target_thread->return_error = BR_OK; } if (target_thread->return_error == BR_OK) { - if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION) - printk(KERN_INFO "binder: send failed reply for transaction %d to %d:%d\n", - t->debug_id, target_thread->proc->pid, target_thread->pid); + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "binder: send failed reply for " + "transaction %d to %d:%d\n", + t->debug_id, target_thread->proc->pid, + target_thread->pid); binder_pop_transaction(target_thread, t); target_thread->return_error = error_code; @@ -1234,29 +1262,100 @@ static void binder_send_failed_reply(struct binder_transaction *t, } else { struct binder_transaction *next = t->from_parent; - if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION) - printk(KERN_INFO "binder: send failed reply " - "for transaction %d, target dead\n", - t->debug_id); + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "binder: send failed reply " + "for transaction %d, target dead\n", + t->debug_id); binder_pop_transaction(target_thread, t); if (next == NULL) { - if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) - printk(KERN_INFO "binder: reply failed," - " no target thread at root\n"); + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "binder: reply failed," + " no target thread at root\n"); return; } t = next; - if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) - printk(KERN_INFO "binder: reply failed, no targ" - "et thread -- retry %d\n", t->debug_id); + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "binder: reply failed, no target " + "thread -- retry %d\n", t->debug_id); } } } static void binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer *buffer, - size_t *failed_at); + size_t *failed_at) +{ + size_t *offp, *off_end; + int debug_id = buffer->debug_id; + + binder_debug(BINDER_DEBUG_TRANSACTION, + "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", + proc->pid, buffer->debug_id, + buffer->data_size, buffer->offsets_size, failed_at); + + if (buffer->target_node) + binder_dec_node(buffer->target_node, 1, 0); + + offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *))); + if (failed_at) + off_end = failed_at; + else + off_end = (void *)offp + buffer->offsets_size; + for (; offp < off_end; offp++) { + struct flat_binder_object *fp; + if (*offp > buffer->data_size - sizeof(*fp) || + buffer->data_size < sizeof(*fp) || + !IS_ALIGNED(*offp, sizeof(void *))) { + printk(KERN_ERR "binder: transaction release %d bad" + "offset %zd, size %zd\n", debug_id, + *offp, buffer->data_size); + continue; + } + fp = (struct flat_binder_object *)(buffer->data + *offp); + switch (fp->type) { + case BINDER_TYPE_BINDER: + case BINDER_TYPE_WEAK_BINDER: { + struct binder_node *node = binder_get_node(proc, fp->binder); + if (node == NULL) { + printk(KERN_ERR "binder: transaction release %d" + " bad node %p\n", debug_id, fp->binder); + break; + } + binder_debug(BINDER_DEBUG_TRANSACTION, + " node %d u%p\n", + node->debug_id, node->ptr); + binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0); + } break; + case BINDER_TYPE_HANDLE: + case BINDER_TYPE_WEAK_HANDLE: { + struct binder_ref *ref = binder_get_ref(proc, fp->handle); + if (ref == NULL) { + printk(KERN_ERR "binder: transaction release %d" + " bad handle %ld\n", debug_id, + fp->handle); + break; + } + binder_debug(BINDER_DEBUG_TRANSACTION, + " ref %d desc %d (node %d)\n", + ref->debug_id, ref->desc, ref->node->debug_id); + binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE); + } break; + + case BINDER_TYPE_FD: + binder_debug(BINDER_DEBUG_TRANSACTION, + " fd %ld\n", fp->handle); + if (failed_at) + task_close_fd(proc, fp->handle); + break; + + default: + printk(KERN_ERR "binder: transaction release %d bad " + "object type %lx\n", debug_id, fp->type); + break; + } + } +} static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, @@ -1387,34 +1486,34 @@ static void binder_transaction(struct binder_proc *proc, return_error = BR_FAILED_REPLY; goto err_alloc_t_failed; } - binder_stats.obj_created[BINDER_STAT_TRANSACTION]++; + binder_stats_created(BINDER_STAT_TRANSACTION); tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); if (tcomplete == NULL) { return_error = BR_FAILED_REPLY; goto err_alloc_tcomplete_failed; } - binder_stats.obj_created[BINDER_STAT_TRANSACTION_COMPLETE]++; + binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); t->debug_id = ++binder_last_id; e->debug_id = t->debug_id; - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) { - if (reply) - printk(KERN_INFO "binder: %d:%d BC_REPLY %d -> %d:%d, " - "data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_thread->pid, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - else - printk(KERN_INFO "binder: %d:%d BC_TRANSACTION %d -> " - "%d - node %d, data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_node->debug_id, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - } + if (reply) + binder_debug(BINDER_DEBUG_TRANSACTION, + "binder: %d:%d BC_REPLY %d -> %d:%d, " + "data %p-%p size %zd-%zd\n", + proc->pid, thread->pid, t->debug_id, + target_proc->pid, target_thread->pid, + tr->data.ptr.buffer, tr->data.ptr.offsets, + tr->data_size, tr->offsets_size); + else + binder_debug(BINDER_DEBUG_TRANSACTION, + "binder: %d:%d BC_TRANSACTION %d -> " + "%d - node %d, data %p-%p size %zd-%zd\n", + proc->pid, thread->pid, t->debug_id, + target_proc->pid, target_node->debug_id, + tr->data.ptr.buffer, tr->data.ptr.offsets, + tr->data_size, tr->offsets_size); if (!reply && !(tr->flags & TF_ONE_WAY)) t->from = thread; @@ -1505,10 +1604,13 @@ static void binder_transaction(struct binder_proc *proc, else fp->type = BINDER_TYPE_WEAK_HANDLE; fp->handle = ref->desc; - binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, &thread->todo); - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " node %d u%p -> ref %d desc %d\n", - node->debug_id, node->ptr, ref->debug_id, ref->desc); + binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, + &thread->todo); + + binder_debug(BINDER_DEBUG_TRANSACTION, + " node %d u%p -> ref %d desc %d\n", + node->debug_id, node->ptr, ref->debug_id, + ref->desc); } break; case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { @@ -1529,9 +1631,10 @@ static void binder_transaction(struct binder_proc *proc, fp->binder = ref->node->ptr; fp->cookie = ref->node->cookie; binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " ref %d desc %d -> node %d u%p\n", - ref->debug_id, ref->desc, ref->node->debug_id, ref->node->ptr); + binder_debug(BINDER_DEBUG_TRANSACTION, + " ref %d desc %d -> node %d u%p\n", + ref->debug_id, ref->desc, ref->node->debug_id, + ref->node->ptr); } else { struct binder_ref *new_ref; new_ref = binder_get_ref_for_node(target_proc, ref->node); @@ -1541,9 +1644,10 @@ static void binder_transaction(struct binder_proc *proc, } fp->handle = new_ref->desc; binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " ref %d desc %d -> ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, new_ref->debug_id, new_ref->desc, ref->node->debug_id); + binder_debug(BINDER_DEBUG_TRANSACTION, + " ref %d desc %d -> ref %d desc %d (node %d)\n", + ref->debug_id, ref->desc, new_ref->debug_id, + new_ref->desc, ref->node->debug_id); } } break; @@ -1579,8 +1683,8 @@ static void binder_transaction(struct binder_proc *proc, goto err_get_unused_fd_failed; } task_fd_install(target_proc, target_fd, file); - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd); + binder_debug(BINDER_DEBUG_TRANSACTION, + " fd %ld -> %d\n", fp->handle, target_fd); /* TODO: fput? */ fp->handle = target_fd; } break; @@ -1632,21 +1736,20 @@ err_copy_data_failed: binder_free_buf(target_proc, t->buffer); err_binder_alloc_buf_failed: kfree(tcomplete); - binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++; + binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); err_alloc_tcomplete_failed: kfree(t); - binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++; + binder_stats_deleted(BINDER_STAT_TRANSACTION); err_alloc_t_failed: err_bad_call_stack: err_empty_call_stack: err_dead_binder: err_invalid_target_handle: err_no_context_mgr_node: - if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION) - printk(KERN_INFO "binder: %d:%d transaction failed %d, size" - "%zd-%zd\n", - proc->pid, thread->pid, return_error, - tr->data_size, tr->offsets_size); + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "binder: %d:%d transaction failed %d, size %zd-%zd\n", + proc->pid, thread->pid, return_error, + tr->data_size, tr->offsets_size); { struct binder_transaction_log_entry *fe; @@ -1662,76 +1765,6 @@ err_no_context_mgr_node: thread->return_error = return_error; } -static void binder_transaction_buffer_release(struct binder_proc *proc, - struct binder_buffer *buffer, - size_t *failed_at) -{ - size_t *offp, *off_end; - int debug_id = buffer->debug_id; - - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", - proc->pid, buffer->debug_id, - buffer->data_size, buffer->offsets_size, failed_at); - - if (buffer->target_node) - binder_dec_node(buffer->target_node, 1, 0); - - offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *))); - if (failed_at) - off_end = failed_at; - else - off_end = (void *)offp + buffer->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > buffer->data_size - sizeof(*fp) || - buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - printk(KERN_ERR "binder: transaction release %d bad" - "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); - continue; - } - fp = (struct flat_binder_object *)(buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - printk(KERN_ERR "binder: transaction release %d bad node %p\n", debug_id, fp->binder); - break; - } - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " node %d u%p\n", - node->debug_id, node->ptr); - binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - printk(KERN_ERR "binder: transaction release %d bad handle %ld\n", debug_id, fp->handle); - break; - } - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, ref->node->debug_id); - binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE); - } break; - - case BINDER_TYPE_FD: - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO " fd %ld\n", fp->handle); - if (failed_at) - task_close_fd(proc, fp->handle); - break; - - default: - printk(KERN_ERR "binder: transaction release %d bad object type %lx\n", debug_id, fp->type); - break; - } - } -} - int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, void __user *buffer, int size, signed long *consumed) { @@ -1799,9 +1832,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, binder_dec_ref(ref, 0); break; } - if (binder_debug_mask & BINDER_DEBUG_USER_REFS) - printk(KERN_INFO "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, debug_string, ref->debug_id, ref->desc, ref->strong, ref->weak, ref->node->debug_id); + binder_debug(BINDER_DEBUG_USER_REFS, + "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", + proc->pid, thread->pid, debug_string, ref->debug_id, + ref->desc, ref->strong, ref->weak, ref->node->debug_id); break; } case BC_INCREFS_DONE: @@ -1859,9 +1893,11 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, node->pending_weak_ref = 0; } binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); - if (binder_debug_mask & BINDER_DEBUG_USER_REFS) - printk(KERN_INFO "binder: %d:%d %s node %d ls %d lw %d\n", - proc->pid, thread->pid, cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", node->debug_id, node->local_strong_refs, node->local_weak_refs); + binder_debug(BINDER_DEBUG_USER_REFS, + "binder: %d:%d %s node %d ls %d lw %d\n", + proc->pid, thread->pid, + cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", + node->debug_id, node->local_strong_refs, node->local_weak_refs); break; } case BC_ATTEMPT_ACQUIRE: @@ -1893,10 +1929,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, proc->pid, thread->pid, data_ptr); break; } - if (binder_debug_mask & BINDER_DEBUG_FREE_BUFFER) - printk(KERN_INFO "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", - proc->pid, thread->pid, data_ptr, buffer->debug_id, - buffer->transaction ? "active" : "finished"); + binder_debug(BINDER_DEBUG_FREE_BUFFER, + "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", + proc->pid, thread->pid, data_ptr, buffer->debug_id, + buffer->transaction ? "active" : "finished"); if (buffer->transaction) { buffer->transaction->buffer = NULL; @@ -1926,9 +1962,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } case BC_REGISTER_LOOPER: - if (binder_debug_mask & BINDER_DEBUG_THREADS) - printk(KERN_INFO "binder: %d:%d BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_THREADS, + "binder: %d:%d BC_REGISTER_LOOPER\n", + proc->pid, thread->pid); if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { thread->looper |= BINDER_LOOPER_STATE_INVALID; binder_user_error("binder: %d:%d ERROR:" @@ -1948,9 +1984,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, thread->looper |= BINDER_LOOPER_STATE_REGISTERED; break; case BC_ENTER_LOOPER: - if (binder_debug_mask & BINDER_DEBUG_THREADS) - printk(KERN_INFO "binder: %d:%d BC_ENTER_LOOPER\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_THREADS, + "binder: %d:%d BC_ENTER_LOOPER\n", + proc->pid, thread->pid); if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { thread->looper |= BINDER_LOOPER_STATE_INVALID; binder_user_error("binder: %d:%d ERROR:" @@ -1961,9 +1997,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, thread->looper |= BINDER_LOOPER_STATE_ENTERED; break; case BC_EXIT_LOOPER: - if (binder_debug_mask & BINDER_DEBUG_THREADS) - printk(KERN_INFO "binder: %d:%d BC_EXIT_LOOPER\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_THREADS, + "binder: %d:%d BC_EXIT_LOOPER\n", + proc->pid, thread->pid); thread->looper |= BINDER_LOOPER_STATE_EXITED; break; @@ -1992,14 +2028,14 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, break; } - if (binder_debug_mask & BINDER_DEBUG_DEATH_NOTIFICATION) - printk(KERN_INFO "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - cookie, ref->debug_id, ref->desc, - ref->strong, ref->weak, ref->node->debug_id); + binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, + "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", + proc->pid, thread->pid, + cmd == BC_REQUEST_DEATH_NOTIFICATION ? + "BC_REQUEST_DEATH_NOTIFICATION" : + "BC_CLEAR_DEATH_NOTIFICATION", + cookie, ref->debug_id, ref->desc, + ref->strong, ref->weak, ref->node->debug_id); if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { if (ref->death) { @@ -2013,13 +2049,13 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, death = kzalloc(sizeof(*death), GFP_KERNEL); if (death == NULL) { thread->return_error = BR_ERROR; - if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION) - printk(KERN_INFO "binder: %d:%d " - "BC_REQUEST_DEATH_NOTIFICATION failed\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "binder: %d:%d " + "BC_REQUEST_DEATH_NOTIFICATION failed\n", + proc->pid, thread->pid); break; } - binder_stats.obj_created[BINDER_STAT_DEATH]++; + binder_stats_created(BINDER_STAT_DEATH); INIT_LIST_HEAD(&death->work.entry); death->cookie = cookie; ref->death = death; @@ -2082,9 +2118,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, break; } } - if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) - printk(KERN_INFO "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", - proc->pid, thread->pid, cookie, death); + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", + proc->pid, thread->pid, cookie, death); if (death == NULL) { binder_user_error("binder: %d:%d BC_DEAD" "_BINDER_DONE %p not found\n", @@ -2240,13 +2276,13 @@ retry: ptr += sizeof(uint32_t); binder_stat_br(proc, thread, cmd); - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION_COMPLETE) - printk(KERN_INFO "binder: %d:%d BR_TRANSACTION_COMPLETE\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, + "binder: %d:%d BR_TRANSACTION_COMPLETE\n", + proc->pid, thread->pid); list_del(&w->entry); kfree(w); - binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++; + binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); } break; case BINDER_WORK_NODE: { struct binder_node *node = container_of(w, struct binder_node, work); @@ -2287,22 +2323,24 @@ retry: ptr += sizeof(void *); binder_stat_br(proc, thread, cmd); - if (binder_debug_mask & BINDER_DEBUG_USER_REFS) - printk(KERN_INFO "binder: %d:%d %s %d u%p c%p\n", - proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); + binder_debug(BINDER_DEBUG_USER_REFS, + "binder: %d:%d %s %d u%p c%p\n", + proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); } else { list_del_init(&w->entry); if (!weak && !strong) { - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: %d:%d node %d u%p c%p deleted\n", - proc->pid, thread->pid, node->debug_id, node->ptr, node->cookie); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: %d:%d node %d u%p c%p deleted\n", + proc->pid, thread->pid, node->debug_id, + node->ptr, node->cookie); rb_erase(&node->rb_node, &proc->nodes); kfree(node); - binder_stats.obj_deleted[BINDER_STAT_NODE]++; + binder_stats_deleted(BINDER_STAT_NODE); } else { - if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS) - printk(KERN_INFO "binder: %d:%d node %d u%p c%p state unchanged\n", - proc->pid, thread->pid, node->debug_id, node->ptr, node->cookie); + binder_debug(BINDER_DEBUG_INTERNAL_REFS, + "binder: %d:%d node %d u%p c%p state unchanged\n", + proc->pid, thread->pid, node->debug_id, node->ptr, + node->cookie); } } } break; @@ -2323,18 +2361,18 @@ retry: if (put_user(death->cookie, (void * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); - if (binder_debug_mask & BINDER_DEBUG_DEATH_NOTIFICATION) - printk(KERN_INFO "binder: %d:%d %s %p\n", - proc->pid, thread->pid, - cmd == BR_DEAD_BINDER ? - "BR_DEAD_BINDER" : - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - death->cookie); + binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, + "binder: %d:%d %s %p\n", + proc->pid, thread->pid, + cmd == BR_DEAD_BINDER ? + "BR_DEAD_BINDER" : + "BR_CLEAR_DEATH_NOTIFICATION_DONE", + death->cookie); if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { list_del(&w->entry); kfree(death); - binder_stats.obj_deleted[BINDER_STAT_DEATH]++; + binder_stats_deleted(BINDER_STAT_DEATH); } else list_move(&w->entry, &proc->delivered_death); if (cmd == BR_DEAD_BINDER) @@ -2391,16 +2429,16 @@ retry: ptr += sizeof(tr); binder_stat_br(proc, thread, cmd); - if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) - printk(KERN_INFO "binder: %d:%d %s %d %d:%d, cmd %d" - "size %zd-%zd ptr %p-%p\n", - proc->pid, thread->pid, - (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : - "BR_REPLY", - t->debug_id, t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, cmd, - t->buffer->data_size, t->buffer->offsets_size, - tr.data.ptr.buffer, tr.data.ptr.offsets); + binder_debug(BINDER_DEBUG_TRANSACTION, + "binder: %d:%d %s %d %d:%d, cmd %d" + "size %zd-%zd ptr %p-%p\n", + proc->pid, thread->pid, + (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : + "BR_REPLY", + t->debug_id, t->from ? t->from->proc->pid : 0, + t->from ? t->from->pid : 0, cmd, + t->buffer->data_size, t->buffer->offsets_size, + tr.data.ptr.buffer, tr.data.ptr.offsets); list_del(&t->work.entry); t->buffer->allow_user_free = 1; @@ -2411,7 +2449,7 @@ retry: } else { t->buffer->transaction = NULL; kfree(t); - binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++; + binder_stats_deleted(BINDER_STAT_TRANSACTION); } break; } @@ -2425,9 +2463,9 @@ done: BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ /*spawn a new thread if we leave this out */) { proc->requested_threads++; - if (binder_debug_mask & BINDER_DEBUG_THREADS) - printk(KERN_INFO "binder: %d:%d BR_SPAWN_LOOPER\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_THREADS, + "binder: %d:%d BR_SPAWN_LOOPER\n", + proc->pid, thread->pid); if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) return -EFAULT; } @@ -2450,7 +2488,7 @@ static void binder_release_work(struct list_head *list) } break; case BINDER_WORK_TRANSACTION_COMPLETE: { kfree(w); - binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++; + binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); } break; default: break; @@ -2480,7 +2518,7 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc) thread = kzalloc(sizeof(*thread), GFP_KERNEL); if (thread == NULL) return NULL; - binder_stats.obj_created[BINDER_STAT_THREAD]++; + binder_stats_created(BINDER_STAT_THREAD); thread->proc = proc; thread->pid = current->pid; init_waitqueue_head(&thread->wait); @@ -2507,11 +2545,12 @@ static int binder_free_thread(struct binder_proc *proc, send_reply = t; while (t) { active_transactions++; - if (binder_debug_mask & BINDER_DEBUG_DEAD_TRANSACTION) - printk(KERN_INFO "binder: release %d:%d transaction %d " - "%s, still active\n", proc->pid, thread->pid, - t->debug_id, - (t->to_thread == thread) ? "in" : "out"); + binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, + "binder: release %d:%d transaction %d " + "%s, still active\n", proc->pid, thread->pid, + t->debug_id, + (t->to_thread == thread) ? "in" : "out"); + if (t->to_thread == thread) { t->to_proc = NULL; t->to_thread = NULL; @@ -2530,7 +2569,7 @@ static int binder_free_thread(struct binder_proc *proc, binder_send_failed_reply(send_reply, BR_DEAD_REPLY); binder_release_work(&thread->todo); kfree(thread); - binder_stats.obj_deleted[BINDER_STAT_THREAD]++; + binder_stats_deleted(BINDER_STAT_THREAD); return active_transactions; } @@ -2596,9 +2635,11 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = -EFAULT; goto err; } - if (binder_debug_mask & BINDER_DEBUG_READ_WRITE) - printk(KERN_INFO "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", - proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, bwr.read_size, bwr.read_buffer); + binder_debug(BINDER_DEBUG_READ_WRITE, + "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", + proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, + bwr.read_size, bwr.read_buffer); + if (bwr.write_size > 0) { ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); if (ret < 0) { @@ -2618,9 +2659,10 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; } } - if (binder_debug_mask & BINDER_DEBUG_READ_WRITE) - printk(KERN_INFO "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", - proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, bwr.read_consumed, bwr.read_size); + binder_debug(BINDER_DEBUG_READ_WRITE, + "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", + proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, + bwr.read_consumed, bwr.read_size); if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { ret = -EFAULT; goto err; @@ -2661,9 +2703,8 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) binder_context_mgr_node->has_weak_ref = 1; break; case BINDER_THREAD_EXIT: - if (binder_debug_mask & BINDER_DEBUG_THREADS) - printk(KERN_INFO "binder: %d:%d exit\n", - proc->pid, thread->pid); + binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n", + proc->pid, thread->pid); binder_free_thread(proc, thread); thread = NULL; break; @@ -2695,24 +2736,22 @@ err: static void binder_vma_open(struct vm_area_struct *vma) { struct binder_proc *proc = vma->vm_private_data; - if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) - printk(KERN_INFO - "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); + binder_debug(BINDER_DEBUG_OPEN_CLOSE, + "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", + proc->pid, vma->vm_start, vma->vm_end, + (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, + (unsigned long)pgprot_val(vma->vm_page_prot)); dump_stack(); } static void binder_vma_close(struct vm_area_struct *vma) { struct binder_proc *proc = vma->vm_private_data; - if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) - printk(KERN_INFO - "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); + binder_debug(BINDER_DEBUG_OPEN_CLOSE, + "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", + proc->pid, vma->vm_start, vma->vm_end, + (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, + (unsigned long)pgprot_val(vma->vm_page_prot)); proc->vma = NULL; binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); } @@ -2733,12 +2772,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) if ((vma->vm_end - vma->vm_start) > SZ_4M) vma->vm_end = vma->vm_start + SZ_4M; - if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) - printk(KERN_INFO - "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); + binder_debug(BINDER_DEBUG_OPEN_CLOSE, + "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", + proc->pid, vma->vm_start, vma->vm_end, + (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, + (unsigned long)pgprot_val(vma->vm_page_prot)); if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { ret = -EPERM; @@ -2818,9 +2856,8 @@ static int binder_open(struct inode *nodp, struct file *filp) { struct binder_proc *proc; - if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) - printk(KERN_INFO "binder_open: %d:%d\n", - current->group_leader->pid, current->pid); + binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", + current->group_leader->pid, current->pid); proc = kzalloc(sizeof(*proc), GFP_KERNEL); if (proc == NULL) @@ -2831,7 +2868,7 @@ static int binder_open(struct inode *nodp, struct file *filp) init_waitqueue_head(&proc->wait); proc->default_priority = task_nice(current); mutex_lock(&binder_lock); - binder_stats.obj_created[BINDER_STAT_PROC]++; + binder_stats_created(BINDER_STAT_PROC); hlist_add_head(&proc->proc_node, &binder_procs); proc->pid = current->group_leader->pid; INIT_LIST_HEAD(&proc->delivered_death); @@ -2873,8 +2910,9 @@ static void binder_deferred_flush(struct binder_proc *proc) } wake_up_interruptible_all(&proc->wait); - if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) - printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count); + binder_debug(BINDER_DEBUG_OPEN_CLOSE, + "binder_flush: %d woke %d threads\n", proc->pid, + wake_count); } static int binder_release(struct inode *nodp, struct file *filp) @@ -2903,8 +2941,9 @@ static void binder_deferred_release(struct binder_proc *proc) hlist_del(&proc->proc_node); if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { - if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) - printk(KERN_INFO "binder_release: %d context_mgr_node gone\n", proc->pid); + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "binder_release: %d context_mgr_node gone\n", + proc->pid); binder_context_mgr_node = NULL; } @@ -2925,7 +2964,7 @@ static void binder_deferred_release(struct binder_proc *proc) list_del_init(&node->work.entry); if (hlist_empty(&node->refs)) { kfree(node); - binder_stats.obj_deleted[BINDER_STAT_NODE]++; + binder_stats_deleted(BINDER_STAT_NODE); } else { struct binder_ref *ref; int death = 0; @@ -2947,10 +2986,10 @@ static void binder_deferred_release(struct binder_proc *proc) BUG(); } } - if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) - printk(KERN_INFO "binder: node %d now dead, " - "refs %d, death %d\n", node->debug_id, - incoming_refs, death); + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "binder: node %d now dead, " + "refs %d, death %d\n", node->debug_id, + incoming_refs, death); } } outgoing_refs = 0; @@ -2979,20 +3018,18 @@ static void binder_deferred_release(struct binder_proc *proc) buffers++; } - binder_stats.obj_deleted[BINDER_STAT_PROC]++; + binder_stats_deleted(BINDER_STAT_PROC); page_count = 0; if (proc->pages) { int i; for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) { if (proc->pages[i]) { - if (binder_debug_mask & - BINDER_DEBUG_BUFFER_ALLOC) - printk(KERN_INFO - "binder_release: %d: " - "page %d at %p not freed\n", - proc->pid, i, - proc->buffer + i * PAGE_SIZE); + binder_debug(BINDER_DEBUG_BUFFER_ALLOC, + "binder_release: %d: " + "page %d at %p not freed\n", + proc->pid, i, + proc->buffer + i * PAGE_SIZE); __free_page(proc->pages[i]); page_count++; } @@ -3003,13 +3040,12 @@ static void binder_deferred_release(struct binder_proc *proc) put_task_struct(proc->tsk); - if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) - printk(KERN_INFO - "binder_release: %d threads %d, nodes %d (ref %d), " - "refs %d, active transactions %d, buffers %d, " - "pages %d\n", - proc->pid, threads, nodes, incoming_refs, outgoing_refs, - active_transactions, buffers, page_count); + binder_debug(BINDER_DEBUG_OPEN_CLOSE, + "binder_release: %d threads %d, nodes %d (ref %d), " + "refs %d, active transactions %d, buffers %d, " + "pages %d\n", + proc->pid, threads, nodes, incoming_refs, outgoing_refs, + active_transactions, buffers, page_count); kfree(proc); } @@ -3055,7 +3091,8 @@ static void binder_deferred_func(struct work_struct *work) } static DECLARE_WORK(binder_deferred_work, binder_deferred_func); -static void binder_defer_work(struct binder_proc *proc, int defer) +static void +binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) { mutex_lock(&binder_deferred_lock); proc->deferred_work |= defer; diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index f934393..935d281 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -1,5 +1,21 @@ /* drivers/misc/lowmemorykiller.c * + * The lowmemorykiller driver lets user-space specify a set of memory thresholds + * where processes with a range of oom_adj values will get killed. Specify the + * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the + * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both + * files take a comma separated list of numbers in ascending order. + * + * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and + * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes + * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages + * and kill processes with a oom_adj value of 0 or higher when the free memory + * drops below 1024 pages. + * + * The driver considers memory used for caches to be free, but if a large + * percentage of the cached memory is locked this can be very inaccurate + * and processes may not get killed until the normal oom killer is triggered. + * * Copyright (C) 2007-2008 Google, Inc. * * This software is licensed under the terms of the GNU General Public @@ -19,12 +35,6 @@ #include <linux/oom.h> #include <linux/sched.h> -static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask); - -static struct shrinker lowmem_shrinker = { - .shrink = lowmem_shrink, - .seeks = DEFAULT_SEEKS * 16 -}; static uint32_t lowmem_debug_level = 2; static int lowmem_adj[6] = { 0, @@ -47,13 +57,6 @@ static int lowmem_minfree_size = 4; printk(x); \ } while (0) -module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); -module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, - S_IRUGO | S_IWUSR); -module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, - S_IRUGO | S_IWUSR); -module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR); - static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) { struct task_struct *p; @@ -140,6 +143,11 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) return rem; } +static struct shrinker lowmem_shrinker = { + .shrink = lowmem_shrink, + .seeks = DEFAULT_SEEKS * 16 +}; + static int __init lowmem_init(void) { register_shrinker(&lowmem_shrinker); @@ -151,6 +159,13 @@ static void __exit lowmem_exit(void) unregister_shrinker(&lowmem_shrinker); } +module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); +module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, + S_IRUGO | S_IWUSR); +module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, + S_IRUGO | S_IWUSR); +module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR); + module_init(lowmem_init); module_exit(lowmem_exit); diff --git a/drivers/staging/android/lowmemorykiller.txt b/drivers/staging/android/lowmemorykiller.txt deleted file mode 100644 index bd5c0c0..0000000 --- a/drivers/staging/android/lowmemorykiller.txt +++ /dev/null @@ -1,16 +0,0 @@ -The lowmemorykiller driver lets user-space specify a set of memory thresholds -where processes with a range of oom_adj values will get killed. Specify the -minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the -number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both -files take a comma separated list of numbers in ascending order. - -For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and -"1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes -with a oom_adj value of 8 or higher when the free memory drops below 4096 pages -and kill processes with a oom_adj value of 0 or higher when the free memory -drops below 1024 pages. - -The driver considers memory used for caches to be free, but if a large -percentage of the cached memory is locked this can be very inaccurate -and processes may not get killed until the normal oom killer is triggered. - |