diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 13:31:17 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 13:31:17 -0500 |
| commit | f6cff79f1d122f78a4b35bf4b2f0112afcd89ea4 (patch) | |
| tree | cf3a38576f9adbb3860982c25f72aebed2bb541a /drivers/android | |
| parent | 47fcc0360cfb3fe82e4daddacad3c1cd80b0b75d (diff) | |
| parent | 9ff6576e124b1227c27c1da43fe5f8ee908263e0 (diff) | |
Merge tag 'char-misc-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the big pull request for char/misc drivers for 4.16-rc1.
There's a lot of stuff in here. Three new driver subsystems were added
for various types of hardware busses:
- siox
- slimbus
- soundwire
as well as a new vboxguest subsystem for the VirtualBox hypervisor
drivers.
There's also big updates from the FPGA subsystem, lots of Android
binder fixes, the usual handful of hyper-v updates, and lots of other
smaller driver updates.
All of these have been in linux-next for a long time, with no reported
issues"
* tag 'char-misc-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (155 commits)
char: lp: use true or false for boolean values
android: binder: use VM_ALLOC to get vm area
android: binder: Use true and false for boolean values
lkdtm: fix handle_irq_event symbol for INT_HW_IRQ_EN
EISA: Delete error message for a failed memory allocation in eisa_probe()
EISA: Whitespace cleanup
misc: remove AVR32 dependencies
virt: vbox: Add error mapping for VERR_INVALID_NAME and VERR_NO_MORE_FILES
soundwire: Fix a signedness bug
uio_hv_generic: fix new type mismatch warnings
uio_hv_generic: fix type mismatch warnings
auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
uio_hv_generic: add rescind support
uio_hv_generic: check that host supports monitor page
uio_hv_generic: create send and receive buffers
uio: document uio_hv_generic regions
doc: fix documentation about uio_hv_generic
vmbus: add monitor_id and subchannel_id to sysfs per channel
vmbus: fix ABI documentation
uio_hv_generic: use ISR callback method
...
Diffstat (limited to 'drivers/android')
| -rw-r--r-- | drivers/android/binder.c | 196 | ||||
| -rw-r--r-- | drivers/android/binder_alloc.c | 29 | ||||
| -rw-r--r-- | drivers/android/binder_alloc.h | 4 |
3 files changed, 158 insertions, 71 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index cc89d0d2b965..d21040c5d343 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
| @@ -141,7 +141,7 @@ enum { | |||
| 141 | }; | 141 | }; |
| 142 | static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | | 142 | static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | |
| 143 | BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; | 143 | BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; |
| 144 | module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); | 144 | module_param_named(debug_mask, binder_debug_mask, uint, 0644); |
| 145 | 145 | ||
| 146 | static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES; | 146 | static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES; |
| 147 | module_param_named(devices, binder_devices_param, charp, 0444); | 147 | module_param_named(devices, binder_devices_param, charp, 0444); |
| @@ -160,7 +160,7 @@ static int binder_set_stop_on_user_error(const char *val, | |||
| 160 | return ret; | 160 | return ret; |
| 161 | } | 161 | } |
| 162 | module_param_call(stop_on_user_error, binder_set_stop_on_user_error, | 162 | module_param_call(stop_on_user_error, binder_set_stop_on_user_error, |
| 163 | param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); | 163 | param_get_int, &binder_stop_on_user_error, 0644); |
| 164 | 164 | ||
| 165 | #define binder_debug(mask, x...) \ | 165 | #define binder_debug(mask, x...) \ |
| 166 | do { \ | 166 | do { \ |
| @@ -249,7 +249,7 @@ static struct binder_transaction_log_entry *binder_transaction_log_add( | |||
| 249 | unsigned int cur = atomic_inc_return(&log->cur); | 249 | unsigned int cur = atomic_inc_return(&log->cur); |
| 250 | 250 | ||
| 251 | if (cur >= ARRAY_SIZE(log->entry)) | 251 | if (cur >= ARRAY_SIZE(log->entry)) |
| 252 | log->full = 1; | 252 | log->full = true; |
| 253 | e = &log->entry[cur % ARRAY_SIZE(log->entry)]; | 253 | e = &log->entry[cur % ARRAY_SIZE(log->entry)]; |
| 254 | WRITE_ONCE(e->debug_id_done, 0); | 254 | WRITE_ONCE(e->debug_id_done, 0); |
| 255 | /* | 255 | /* |
| @@ -493,8 +493,6 @@ enum binder_deferred_state { | |||
| 493 | * (protected by @inner_lock) | 493 | * (protected by @inner_lock) |
| 494 | * @todo: list of work for this process | 494 | * @todo: list of work for this process |
| 495 | * (protected by @inner_lock) | 495 | * (protected by @inner_lock) |
| 496 | * @wait: wait queue head to wait for proc work | ||
| 497 | * (invariant after initialized) | ||
| 498 | * @stats: per-process binder statistics | 496 | * @stats: per-process binder statistics |
| 499 | * (atomics, no lock needed) | 497 | * (atomics, no lock needed) |
| 500 | * @delivered_death: list of delivered death notification | 498 | * @delivered_death: list of delivered death notification |
| @@ -537,7 +535,6 @@ struct binder_proc { | |||
| 537 | bool is_dead; | 535 | bool is_dead; |
| 538 | 536 | ||
| 539 | struct list_head todo; | 537 | struct list_head todo; |
| 540 | wait_queue_head_t wait; | ||
| 541 | struct binder_stats stats; | 538 | struct binder_stats stats; |
| 542 | struct list_head delivered_death; | 539 | struct list_head delivered_death; |
| 543 | int max_threads; | 540 | int max_threads; |
| @@ -579,6 +576,8 @@ enum { | |||
| 579 | * (protected by @proc->inner_lock) | 576 | * (protected by @proc->inner_lock) |
| 580 | * @todo: list of work to do for this thread | 577 | * @todo: list of work to do for this thread |
| 581 | * (protected by @proc->inner_lock) | 578 | * (protected by @proc->inner_lock) |
| 579 | * @process_todo: whether work in @todo should be processed | ||
| 580 | * (protected by @proc->inner_lock) | ||
| 582 | * @return_error: transaction errors reported by this thread | 581 | * @return_error: transaction errors reported by this thread |
| 583 | * (only accessed by this thread) | 582 | * (only accessed by this thread) |
| 584 | * @reply_error: transaction errors reported by target thread | 583 | * @reply_error: transaction errors reported by target thread |
| @@ -604,6 +603,7 @@ struct binder_thread { | |||
| 604 | bool looper_need_return; /* can be written by other thread */ | 603 | bool looper_need_return; /* can be written by other thread */ |
| 605 | struct binder_transaction *transaction_stack; | 604 | struct binder_transaction *transaction_stack; |
| 606 | struct list_head todo; | 605 | struct list_head todo; |
| 606 | bool process_todo; | ||
| 607 | struct binder_error return_error; | 607 | struct binder_error return_error; |
| 608 | struct binder_error reply_error; | 608 | struct binder_error reply_error; |
| 609 | wait_queue_head_t wait; | 609 | wait_queue_head_t wait; |
| @@ -789,6 +789,16 @@ static bool binder_worklist_empty(struct binder_proc *proc, | |||
| 789 | return ret; | 789 | return ret; |
| 790 | } | 790 | } |
| 791 | 791 | ||
| 792 | /** | ||
| 793 | * binder_enqueue_work_ilocked() - Add an item to the work list | ||
| 794 | * @work: struct binder_work to add to list | ||
| 795 | * @target_list: list to add work to | ||
| 796 | * | ||
| 797 | * Adds the work to the specified list. Asserts that work | ||
| 798 | * is not already on a list. | ||
| 799 | * | ||
| 800 | * Requires the proc->inner_lock to be held. | ||
| 801 | */ | ||
| 792 | static void | 802 | static void |
| 793 | binder_enqueue_work_ilocked(struct binder_work *work, | 803 | binder_enqueue_work_ilocked(struct binder_work *work, |
| 794 | struct list_head *target_list) | 804 | struct list_head *target_list) |
| @@ -799,22 +809,56 @@ binder_enqueue_work_ilocked(struct binder_work *work, | |||
| 799 | } | 809 | } |
| 800 | 810 | ||
| 801 | /** | 811 | /** |
| 802 | * binder_enqueue_work() - Add an item to the work list | 812 | * binder_enqueue_deferred_thread_work_ilocked() - Add deferred thread work |
| 803 | * @proc: binder_proc associated with list | 813 | * @thread: thread to queue work to |
| 804 | * @work: struct binder_work to add to list | 814 | * @work: struct binder_work to add to list |
| 805 | * @target_list: list to add work to | ||
| 806 | * | 815 | * |
| 807 | * Adds the work to the specified list. Asserts that work | 816 | * Adds the work to the todo list of the thread. Doesn't set the process_todo |
| 808 | * is not already on a list. | 817 | * flag, which means that (if it wasn't already set) the thread will go to |
| 818 | * sleep without handling this work when it calls read. | ||
| 819 | * | ||
| 820 | * Requires the proc->inner_lock to be held. | ||
| 809 | */ | 821 | */ |
| 810 | static void | 822 | static void |
| 811 | binder_enqueue_work(struct binder_proc *proc, | 823 | binder_enqueue_deferred_thread_work_ilocked(struct binder_thread *thread, |
| 812 | struct binder_work *work, | 824 | struct binder_work *work) |
| 813 | struct list_head *target_list) | ||
| 814 | { | 825 | { |
| 815 | binder_inner_proc_lock(proc); | 826 | binder_enqueue_work_ilocked(work, &thread->todo); |
| 816 | binder_enqueue_work_ilocked(work, target_list); | 827 | } |
| 817 | binder_inner_proc_unlock(proc); | 828 | |
| 829 | /** | ||
| 830 | * binder_enqueue_thread_work_ilocked() - Add an item to the thread work list | ||
| 831 | * @thread: thread to queue work to | ||
| 832 | * @work: struct binder_work to add to list | ||
| 833 | * | ||
| 834 | * Adds the work to the todo list of the thread, and enables processing | ||
| 835 | * of the todo queue. | ||
| 836 | * | ||
| 837 | * Requires the proc->inner_lock to be held. | ||
| 838 | */ | ||
| 839 | static void | ||
| 840 | binder_enqueue_thread_work_ilocked(struct binder_thread *thread, | ||
| 841 | struct binder_work *work) | ||
| 842 | { | ||
| 843 | binder_enqueue_work_ilocked(work, &thread->todo); | ||
| 844 | thread->process_todo = true; | ||
| 845 | } | ||
| 846 | |||
| 847 | /** | ||
| 848 | * binder_enqueue_thread_work() - Add an item to the thread work list | ||
| 849 | * @thread: thread to queue work to | ||
| 850 | * @work: struct binder_work to add to list | ||
| 851 | * | ||
| 852 | * Adds the work to the todo list of the thread, and enables processing | ||
| 853 | * of the todo queue. | ||
| 854 | */ | ||
| 855 | static void | ||
| 856 | binder_enqueue_thread_work(struct binder_thread *thread, | ||
| 857 | struct binder_work *work) | ||
| 858 | { | ||
| 859 | binder_inner_proc_lock(thread->proc); | ||
| 860 | binder_enqueue_thread_work_ilocked(thread, work); | ||
| 861 | binder_inner_proc_unlock(thread->proc); | ||
| 818 | } | 862 | } |
| 819 | 863 | ||
| 820 | static void | 864 | static void |
| @@ -940,7 +984,7 @@ err: | |||
| 940 | static bool binder_has_work_ilocked(struct binder_thread *thread, | 984 | static bool binder_has_work_ilocked(struct binder_thread *thread, |
| 941 | bool do_proc_work) | 985 | bool do_proc_work) |
| 942 | { | 986 | { |
| 943 | return !binder_worklist_empty_ilocked(&thread->todo) || | 987 | return thread->process_todo || |
| 944 | thread->looper_need_return || | 988 | thread->looper_need_return || |
| 945 | (do_proc_work && | 989 | (do_proc_work && |
| 946 | !binder_worklist_empty_ilocked(&thread->proc->todo)); | 990 | !binder_worklist_empty_ilocked(&thread->proc->todo)); |
| @@ -1228,6 +1272,17 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong, | |||
| 1228 | node->local_strong_refs++; | 1272 | node->local_strong_refs++; |
| 1229 | if (!node->has_strong_ref && target_list) { | 1273 | if (!node->has_strong_ref && target_list) { |
| 1230 | binder_dequeue_work_ilocked(&node->work); | 1274 | binder_dequeue_work_ilocked(&node->work); |
| 1275 | /* | ||
| 1276 | * Note: this function is the only place where we queue | ||
| 1277 | * directly to a thread->todo without using the | ||
| 1278 | * corresponding binder_enqueue_thread_work() helper | ||
| 1279 | * functions; in this case it's ok to not set the | ||
| 1280 | * process_todo flag, since we know this node work will | ||
| 1281 | * always be followed by other work that starts queue | ||
| 1282 | * processing: in case of synchronous transactions, a | ||
| 1283 | * BR_REPLY or BR_ERROR; in case of oneway | ||
| 1284 | * transactions, a BR_TRANSACTION_COMPLETE. | ||
| 1285 | */ | ||
| 1231 | binder_enqueue_work_ilocked(&node->work, target_list); | 1286 | binder_enqueue_work_ilocked(&node->work, target_list); |
| 1232 | } | 1287 | } |
| 1233 | } else { | 1288 | } else { |
| @@ -1239,6 +1294,9 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong, | |||
| 1239 | node->debug_id); | 1294 | node->debug_id); |
| 1240 | return -EINVAL; | 1295 | return -EINVAL; |
| 1241 | } | 1296 | } |
| 1297 | /* | ||
| 1298 | * See comment above | ||
| 1299 | */ | ||
| 1242 | binder_enqueue_work_ilocked(&node->work, target_list); | 1300 | binder_enqueue_work_ilocked(&node->work, target_list); |
| 1243 | } | 1301 | } |
| 1244 | } | 1302 | } |
| @@ -1928,9 +1986,9 @@ static void binder_send_failed_reply(struct binder_transaction *t, | |||
| 1928 | binder_pop_transaction_ilocked(target_thread, t); | 1986 | binder_pop_transaction_ilocked(target_thread, t); |
| 1929 | if (target_thread->reply_error.cmd == BR_OK) { | 1987 | if (target_thread->reply_error.cmd == BR_OK) { |
| 1930 | target_thread->reply_error.cmd = error_code; | 1988 | target_thread->reply_error.cmd = error_code; |
| 1931 | binder_enqueue_work_ilocked( | 1989 | binder_enqueue_thread_work_ilocked( |
| 1932 | &target_thread->reply_error.work, | 1990 | target_thread, |
| 1933 | &target_thread->todo); | 1991 | &target_thread->reply_error.work); |
| 1934 | wake_up_interruptible(&target_thread->wait); | 1992 | wake_up_interruptible(&target_thread->wait); |
| 1935 | } else { | 1993 | } else { |
| 1936 | WARN(1, "Unexpected reply error: %u\n", | 1994 | WARN(1, "Unexpected reply error: %u\n", |
| @@ -2569,20 +2627,18 @@ static bool binder_proc_transaction(struct binder_transaction *t, | |||
| 2569 | struct binder_proc *proc, | 2627 | struct binder_proc *proc, |
| 2570 | struct binder_thread *thread) | 2628 | struct binder_thread *thread) |
| 2571 | { | 2629 | { |
| 2572 | struct list_head *target_list = NULL; | ||
| 2573 | struct binder_node *node = t->buffer->target_node; | 2630 | struct binder_node *node = t->buffer->target_node; |
| 2574 | bool oneway = !!(t->flags & TF_ONE_WAY); | 2631 | bool oneway = !!(t->flags & TF_ONE_WAY); |
| 2575 | bool wakeup = true; | 2632 | bool pending_async = false; |
| 2576 | 2633 | ||
| 2577 | BUG_ON(!node); | 2634 | BUG_ON(!node); |
| 2578 | binder_node_lock(node); | 2635 | binder_node_lock(node); |
| 2579 | if (oneway) { | 2636 | if (oneway) { |
| 2580 | BUG_ON(thread); | 2637 | BUG_ON(thread); |
| 2581 | if (node->has_async_transaction) { | 2638 | if (node->has_async_transaction) { |
| 2582 | target_list = &node->async_todo; | 2639 | pending_async = true; |
| 2583 | wakeup = false; | ||
| 2584 | } else { | 2640 | } else { |
| 2585 | node->has_async_transaction = 1; | 2641 | node->has_async_transaction = true; |
| 2586 | } | 2642 | } |
| 2587 | } | 2643 | } |
| 2588 | 2644 | ||
| @@ -2594,19 +2650,17 @@ static bool binder_proc_transaction(struct binder_transaction *t, | |||
| 2594 | return false; | 2650 | return false; |
| 2595 | } | 2651 | } |
| 2596 | 2652 | ||
| 2597 | if (!thread && !target_list) | 2653 | if (!thread && !pending_async) |
| 2598 | thread = binder_select_thread_ilocked(proc); | 2654 | thread = binder_select_thread_ilocked(proc); |
| 2599 | 2655 | ||
| 2600 | if (thread) | 2656 | if (thread) |
| 2601 | target_list = &thread->todo; | 2657 | binder_enqueue_thread_work_ilocked(thread, &t->work); |
| 2602 | else if (!target_list) | 2658 | else if (!pending_async) |
| 2603 | target_list = &proc->todo; | 2659 | binder_enqueue_work_ilocked(&t->work, &proc->todo); |
| 2604 | else | 2660 | else |
| 2605 | BUG_ON(target_list != &node->async_todo); | 2661 | binder_enqueue_work_ilocked(&t->work, &node->async_todo); |
| 2606 | 2662 | ||
| 2607 | binder_enqueue_work_ilocked(&t->work, target_list); | 2663 | if (!pending_async) |
| 2608 | |||
| 2609 | if (wakeup) | ||
| 2610 | binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); | 2664 | binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); |
| 2611 | 2665 | ||
| 2612 | binder_inner_proc_unlock(proc); | 2666 | binder_inner_proc_unlock(proc); |
| @@ -3101,10 +3155,10 @@ static void binder_transaction(struct binder_proc *proc, | |||
| 3101 | } | 3155 | } |
| 3102 | } | 3156 | } |
| 3103 | tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; | 3157 | tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; |
| 3104 | binder_enqueue_work(proc, tcomplete, &thread->todo); | ||
| 3105 | t->work.type = BINDER_WORK_TRANSACTION; | 3158 | t->work.type = BINDER_WORK_TRANSACTION; |
| 3106 | 3159 | ||
| 3107 | if (reply) { | 3160 | if (reply) { |
| 3161 | binder_enqueue_thread_work(thread, tcomplete); | ||
| 3108 | binder_inner_proc_lock(target_proc); | 3162 | binder_inner_proc_lock(target_proc); |
| 3109 | if (target_thread->is_dead) { | 3163 | if (target_thread->is_dead) { |
| 3110 | binder_inner_proc_unlock(target_proc); | 3164 | binder_inner_proc_unlock(target_proc); |
| @@ -3112,13 +3166,21 @@ static void binder_transaction(struct binder_proc *proc, | |||
| 3112 | } | 3166 | } |
| 3113 | BUG_ON(t->buffer->async_transaction != 0); | 3167 | BUG_ON(t->buffer->async_transaction != 0); |
| 3114 | binder_pop_transaction_ilocked(target_thread, in_reply_to); | 3168 | binder_pop_transaction_ilocked(target_thread, in_reply_to); |
| 3115 | binder_enqueue_work_ilocked(&t->work, &target_thread->todo); | 3169 | binder_enqueue_thread_work_ilocked(target_thread, &t->work); |
| 3116 | binder_inner_proc_unlock(target_proc); | 3170 | binder_inner_proc_unlock(target_proc); |
| 3117 | wake_up_interruptible_sync(&target_thread->wait); | 3171 | wake_up_interruptible_sync(&target_thread->wait); |
| 3118 | binder_free_transaction(in_reply_to); | 3172 | binder_free_transaction(in_reply_to); |
| 3119 | } else if (!(t->flags & TF_ONE_WAY)) { | 3173 | } else if (!(t->flags & TF_ONE_WAY)) { |
| 3120 | BUG_ON(t->buffer->async_transaction != 0); | 3174 | BUG_ON(t->buffer->async_transaction != 0); |
| 3121 | binder_inner_proc_lock(proc); | 3175 | binder_inner_proc_lock(proc); |
| 3176 | /* | ||
| 3177 | * Defer the TRANSACTION_COMPLETE, so we don't return to | ||
| 3178 | * userspace immediately; this allows the target process to | ||
| 3179 | * immediately start processing this transaction, reducing | ||
| 3180 | * latency. We will then return the TRANSACTION_COMPLETE when | ||
| 3181 | * the target replies (or there is an error). | ||
| 3182 | */ | ||
| 3183 | binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete); | ||
| 3122 | t->need_reply = 1; | 3184 | t->need_reply = 1; |
| 3123 | t->from_parent = thread->transaction_stack; | 3185 | t->from_parent = thread->transaction_stack; |
| 3124 | thread->transaction_stack = t; | 3186 | thread->transaction_stack = t; |
| @@ -3132,6 +3194,7 @@ static void binder_transaction(struct binder_proc *proc, | |||
| 3132 | } else { | 3194 | } else { |
| 3133 | BUG_ON(target_node == NULL); | 3195 | BUG_ON(target_node == NULL); |
| 3134 | BUG_ON(t->buffer->async_transaction != 1); | 3196 | BUG_ON(t->buffer->async_transaction != 1); |
| 3197 | binder_enqueue_thread_work(thread, tcomplete); | ||
| 3135 | if (!binder_proc_transaction(t, target_proc, NULL)) | 3198 | if (!binder_proc_transaction(t, target_proc, NULL)) |
| 3136 | goto err_dead_proc_or_thread; | 3199 | goto err_dead_proc_or_thread; |
| 3137 | } | 3200 | } |
| @@ -3210,15 +3273,11 @@ err_invalid_target_handle: | |||
| 3210 | BUG_ON(thread->return_error.cmd != BR_OK); | 3273 | BUG_ON(thread->return_error.cmd != BR_OK); |
| 3211 | if (in_reply_to) { | 3274 | if (in_reply_to) { |
| 3212 | thread->return_error.cmd = BR_TRANSACTION_COMPLETE; | 3275 | thread->return_error.cmd = BR_TRANSACTION_COMPLETE; |
| 3213 | binder_enqueue_work(thread->proc, | 3276 | binder_enqueue_thread_work(thread, &thread->return_error.work); |
| 3214 | &thread->return_error.work, | ||
| 3215 | &thread->todo); | ||
| 3216 | binder_send_failed_reply(in_reply_to, return_error); | 3277 | binder_send_failed_reply(in_reply_to, return_error); |
| 3217 | } else { | 3278 | } else { |
| 3218 | thread->return_error.cmd = return_error; | 3279 | thread->return_error.cmd = return_error; |
| 3219 | binder_enqueue_work(thread->proc, | 3280 | binder_enqueue_thread_work(thread, &thread->return_error.work); |
| 3220 | &thread->return_error.work, | ||
| 3221 | &thread->todo); | ||
| 3222 | } | 3281 | } |
| 3223 | } | 3282 | } |
| 3224 | 3283 | ||
| @@ -3424,7 +3483,7 @@ static int binder_thread_write(struct binder_proc *proc, | |||
| 3424 | w = binder_dequeue_work_head_ilocked( | 3483 | w = binder_dequeue_work_head_ilocked( |
| 3425 | &buf_node->async_todo); | 3484 | &buf_node->async_todo); |
| 3426 | if (!w) { | 3485 | if (!w) { |
| 3427 | buf_node->has_async_transaction = 0; | 3486 | buf_node->has_async_transaction = false; |
| 3428 | } else { | 3487 | } else { |
| 3429 | binder_enqueue_work_ilocked( | 3488 | binder_enqueue_work_ilocked( |
| 3430 | w, &proc->todo); | 3489 | w, &proc->todo); |
| @@ -3522,10 +3581,9 @@ static int binder_thread_write(struct binder_proc *proc, | |||
| 3522 | WARN_ON(thread->return_error.cmd != | 3581 | WARN_ON(thread->return_error.cmd != |
| 3523 | BR_OK); | 3582 | BR_OK); |
| 3524 | thread->return_error.cmd = BR_ERROR; | 3583 | thread->return_error.cmd = BR_ERROR; |
| 3525 | binder_enqueue_work( | 3584 | binder_enqueue_thread_work( |
| 3526 | thread->proc, | 3585 | thread, |
| 3527 | &thread->return_error.work, | 3586 | &thread->return_error.work); |
| 3528 | &thread->todo); | ||
| 3529 | binder_debug( | 3587 | binder_debug( |
| 3530 | BINDER_DEBUG_FAILED_TRANSACTION, | 3588 | BINDER_DEBUG_FAILED_TRANSACTION, |
| 3531 | "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", | 3589 | "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", |
| @@ -3605,9 +3663,9 @@ static int binder_thread_write(struct binder_proc *proc, | |||
| 3605 | if (thread->looper & | 3663 | if (thread->looper & |
| 3606 | (BINDER_LOOPER_STATE_REGISTERED | | 3664 | (BINDER_LOOPER_STATE_REGISTERED | |
| 3607 | BINDER_LOOPER_STATE_ENTERED)) | 3665 | BINDER_LOOPER_STATE_ENTERED)) |
| 3608 | binder_enqueue_work_ilocked( | 3666 | binder_enqueue_thread_work_ilocked( |
| 3609 | &death->work, | 3667 | thread, |
| 3610 | &thread->todo); | 3668 | &death->work); |
| 3611 | else { | 3669 | else { |
| 3612 | binder_enqueue_work_ilocked( | 3670 | binder_enqueue_work_ilocked( |
| 3613 | &death->work, | 3671 | &death->work, |
| @@ -3662,8 +3720,8 @@ static int binder_thread_write(struct binder_proc *proc, | |||
| 3662 | if (thread->looper & | 3720 | if (thread->looper & |
| 3663 | (BINDER_LOOPER_STATE_REGISTERED | | 3721 | (BINDER_LOOPER_STATE_REGISTERED | |
| 3664 | BINDER_LOOPER_STATE_ENTERED)) | 3722 | BINDER_LOOPER_STATE_ENTERED)) |
| 3665 | binder_enqueue_work_ilocked( | 3723 | binder_enqueue_thread_work_ilocked( |
| 3666 | &death->work, &thread->todo); | 3724 | thread, &death->work); |
| 3667 | else { | 3725 | else { |
| 3668 | binder_enqueue_work_ilocked( | 3726 | binder_enqueue_work_ilocked( |
| 3669 | &death->work, | 3727 | &death->work, |
| @@ -3837,6 +3895,8 @@ retry: | |||
| 3837 | break; | 3895 | break; |
| 3838 | } | 3896 | } |
| 3839 | w = binder_dequeue_work_head_ilocked(list); | 3897 | w = binder_dequeue_work_head_ilocked(list); |
| 3898 | if (binder_worklist_empty_ilocked(&thread->todo)) | ||
| 3899 | thread->process_todo = false; | ||
| 3840 | 3900 | ||
| 3841 | switch (w->type) { | 3901 | switch (w->type) { |
| 3842 | case BINDER_WORK_TRANSACTION: { | 3902 | case BINDER_WORK_TRANSACTION: { |
| @@ -4302,6 +4362,18 @@ static int binder_thread_release(struct binder_proc *proc, | |||
| 4302 | if (t) | 4362 | if (t) |
| 4303 | spin_lock(&t->lock); | 4363 | spin_lock(&t->lock); |
| 4304 | } | 4364 | } |
| 4365 | |||
| 4366 | /* | ||
| 4367 | * If this thread used poll, make sure we remove the waitqueue | ||
| 4368 | * from any epoll data structures holding it with POLLFREE. | ||
| 4369 | * waitqueue_active() is safe to use here because we're holding | ||
| 4370 | * the inner lock. | ||
| 4371 | */ | ||
| 4372 | if ((thread->looper & BINDER_LOOPER_STATE_POLL) && | ||
| 4373 | waitqueue_active(&thread->wait)) { | ||
| 4374 | wake_up_poll(&thread->wait, POLLHUP | POLLFREE); | ||
| 4375 | } | ||
| 4376 | |||
| 4305 | binder_inner_proc_unlock(thread->proc); | 4377 | binder_inner_proc_unlock(thread->proc); |
| 4306 | 4378 | ||
| 4307 | if (send_reply) | 4379 | if (send_reply) |
| @@ -4646,7 +4718,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 4646 | return 0; | 4718 | return 0; |
| 4647 | 4719 | ||
| 4648 | err_bad_arg: | 4720 | err_bad_arg: |
| 4649 | pr_err("binder_mmap: %d %lx-%lx %s failed %d\n", | 4721 | pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, |
| 4650 | proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); | 4722 | proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); |
| 4651 | return ret; | 4723 | return ret; |
| 4652 | } | 4724 | } |
| @@ -4656,7 +4728,7 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
| 4656 | struct binder_proc *proc; | 4728 | struct binder_proc *proc; |
| 4657 | struct binder_device *binder_dev; | 4729 | struct binder_device *binder_dev; |
| 4658 | 4730 | ||
| 4659 | binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", | 4731 | binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__, |
| 4660 | current->group_leader->pid, current->pid); | 4732 | current->group_leader->pid, current->pid); |
| 4661 | 4733 | ||
| 4662 | proc = kzalloc(sizeof(*proc), GFP_KERNEL); | 4734 | proc = kzalloc(sizeof(*proc), GFP_KERNEL); |
| @@ -4695,7 +4767,7 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
| 4695 | * anyway print all contexts that a given PID has, so this | 4767 | * anyway print all contexts that a given PID has, so this |
| 4696 | * is not a problem. | 4768 | * is not a problem. |
| 4697 | */ | 4769 | */ |
| 4698 | proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO, | 4770 | proc->debugfs_entry = debugfs_create_file(strbuf, 0444, |
| 4699 | binder_debugfs_dir_entry_proc, | 4771 | binder_debugfs_dir_entry_proc, |
| 4700 | (void *)(unsigned long)proc->pid, | 4772 | (void *)(unsigned long)proc->pid, |
| 4701 | &binder_proc_fops); | 4773 | &binder_proc_fops); |
| @@ -5524,7 +5596,9 @@ static int __init binder_init(void) | |||
| 5524 | struct binder_device *device; | 5596 | struct binder_device *device; |
| 5525 | struct hlist_node *tmp; | 5597 | struct hlist_node *tmp; |
| 5526 | 5598 | ||
| 5527 | binder_alloc_shrinker_init(); | 5599 | ret = binder_alloc_shrinker_init(); |
| 5600 | if (ret) | ||
| 5601 | return ret; | ||
| 5528 | 5602 | ||
| 5529 | atomic_set(&binder_transaction_log.cur, ~0U); | 5603 | atomic_set(&binder_transaction_log.cur, ~0U); |
| 5530 | atomic_set(&binder_transaction_log_failed.cur, ~0U); | 5604 | atomic_set(&binder_transaction_log_failed.cur, ~0U); |
| @@ -5536,27 +5610,27 @@ static int __init binder_init(void) | |||
| 5536 | 5610 | ||
| 5537 | if (binder_debugfs_dir_entry_root) { | 5611 | if (binder_debugfs_dir_entry_root) { |
| 5538 | debugfs_create_file("state", | 5612 | debugfs_create_file("state", |
| 5539 | S_IRUGO, | 5613 | 0444, |
| 5540 | binder_debugfs_dir_entry_root, | 5614 | binder_debugfs_dir_entry_root, |
| 5541 | NULL, | 5615 | NULL, |
| 5542 | &binder_state_fops); | 5616 | &binder_state_fops); |
| 5543 | debugfs_create_file("stats", | 5617 | debugfs_create_file("stats", |
| 5544 | S_IRUGO, | 5618 | 0444, |
| 5545 | binder_debugfs_dir_entry_root, | 5619 | binder_debugfs_dir_entry_root, |
| 5546 | NULL, | 5620 | NULL, |
| 5547 | &binder_stats_fops); | 5621 | &binder_stats_fops); |
| 5548 | debugfs_create_file("transactions", | 5622 | debugfs_create_file("transactions", |
| 5549 | S_IRUGO, | 5623 | 0444, |
| 5550 | binder_debugfs_dir_entry_root, | 5624 | binder_debugfs_dir_entry_root, |
| 5551 | NULL, | 5625 | NULL, |
| 5552 | &binder_transactions_fops); | 5626 | &binder_transactions_fops); |
| 5553 | debugfs_create_file("transaction_log", | 5627 | debugfs_create_file("transaction_log", |
| 5554 | S_IRUGO, | 5628 | 0444, |
| 5555 | binder_debugfs_dir_entry_root, | 5629 | binder_debugfs_dir_entry_root, |
| 5556 | &binder_transaction_log, | 5630 | &binder_transaction_log, |
| 5557 | &binder_transaction_log_fops); | 5631 | &binder_transaction_log_fops); |
| 5558 | debugfs_create_file("failed_transaction_log", | 5632 | debugfs_create_file("failed_transaction_log", |
| 5559 | S_IRUGO, | 5633 | 0444, |
| 5560 | binder_debugfs_dir_entry_root, | 5634 | binder_debugfs_dir_entry_root, |
| 5561 | &binder_transaction_log_failed, | 5635 | &binder_transaction_log_failed, |
| 5562 | &binder_transaction_log_fops); | 5636 | &binder_transaction_log_fops); |
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 6f6f745605af..5a426c877dfb 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c | |||
| @@ -281,6 +281,9 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, | |||
| 281 | goto err_vm_insert_page_failed; | 281 | goto err_vm_insert_page_failed; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | if (index + 1 > alloc->pages_high) | ||
| 285 | alloc->pages_high = index + 1; | ||
| 286 | |||
| 284 | trace_binder_alloc_page_end(alloc, index); | 287 | trace_binder_alloc_page_end(alloc, index); |
| 285 | /* vm_insert_page does not seem to increment the refcount */ | 288 | /* vm_insert_page does not seem to increment the refcount */ |
| 286 | } | 289 | } |
| @@ -324,11 +327,12 @@ err_no_vma: | |||
| 324 | return vma ? -ENOMEM : -ESRCH; | 327 | return vma ? -ENOMEM : -ESRCH; |
| 325 | } | 328 | } |
| 326 | 329 | ||
| 327 | struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, | 330 | static struct binder_buffer *binder_alloc_new_buf_locked( |
| 328 | size_t data_size, | 331 | struct binder_alloc *alloc, |
| 329 | size_t offsets_size, | 332 | size_t data_size, |
| 330 | size_t extra_buffers_size, | 333 | size_t offsets_size, |
| 331 | int is_async) | 334 | size_t extra_buffers_size, |
| 335 | int is_async) | ||
| 332 | { | 336 | { |
| 333 | struct rb_node *n = alloc->free_buffers.rb_node; | 337 | struct rb_node *n = alloc->free_buffers.rb_node; |
| 334 | struct binder_buffer *buffer; | 338 | struct binder_buffer *buffer; |
| @@ -666,7 +670,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, | |||
| 666 | goto err_already_mapped; | 670 | goto err_already_mapped; |
| 667 | } | 671 | } |
| 668 | 672 | ||
| 669 | area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); | 673 | area = get_vm_area(vma->vm_end - vma->vm_start, VM_ALLOC); |
| 670 | if (area == NULL) { | 674 | if (area == NULL) { |
| 671 | ret = -ENOMEM; | 675 | ret = -ENOMEM; |
| 672 | failure_string = "get_vm_area"; | 676 | failure_string = "get_vm_area"; |
| @@ -853,6 +857,7 @@ void binder_alloc_print_pages(struct seq_file *m, | |||
| 853 | } | 857 | } |
| 854 | mutex_unlock(&alloc->mutex); | 858 | mutex_unlock(&alloc->mutex); |
| 855 | seq_printf(m, " pages: %d:%d:%d\n", active, lru, free); | 859 | seq_printf(m, " pages: %d:%d:%d\n", active, lru, free); |
| 860 | seq_printf(m, " pages high watermark: %zu\n", alloc->pages_high); | ||
| 856 | } | 861 | } |
| 857 | 862 | ||
| 858 | /** | 863 | /** |
| @@ -1002,8 +1007,14 @@ void binder_alloc_init(struct binder_alloc *alloc) | |||
| 1002 | INIT_LIST_HEAD(&alloc->buffers); | 1007 | INIT_LIST_HEAD(&alloc->buffers); |
| 1003 | } | 1008 | } |
| 1004 | 1009 | ||
| 1005 | void binder_alloc_shrinker_init(void) | 1010 | int binder_alloc_shrinker_init(void) |
| 1006 | { | 1011 | { |
| 1007 | list_lru_init(&binder_alloc_lru); | 1012 | int ret = list_lru_init(&binder_alloc_lru); |
| 1008 | register_shrinker(&binder_shrinker); | 1013 | |
| 1014 | if (ret == 0) { | ||
| 1015 | ret = register_shrinker(&binder_shrinker); | ||
| 1016 | if (ret) | ||
| 1017 | list_lru_destroy(&binder_alloc_lru); | ||
| 1018 | } | ||
| 1019 | return ret; | ||
| 1009 | } | 1020 | } |
diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index 2dd33b6df104..9ef64e563856 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h | |||
| @@ -92,6 +92,7 @@ struct binder_lru_page { | |||
| 92 | * @pages: array of binder_lru_page | 92 | * @pages: array of binder_lru_page |
| 93 | * @buffer_size: size of address space specified via mmap | 93 | * @buffer_size: size of address space specified via mmap |
| 94 | * @pid: pid for associated binder_proc (invariant after init) | 94 | * @pid: pid for associated binder_proc (invariant after init) |
| 95 | * @pages_high: high watermark of offset in @pages | ||
| 95 | * | 96 | * |
| 96 | * Bookkeeping structure for per-proc address space management for binder | 97 | * Bookkeeping structure for per-proc address space management for binder |
| 97 | * buffers. It is normally initialized during binder_init() and binder_mmap() | 98 | * buffers. It is normally initialized during binder_init() and binder_mmap() |
| @@ -112,6 +113,7 @@ struct binder_alloc { | |||
| 112 | size_t buffer_size; | 113 | size_t buffer_size; |
| 113 | uint32_t buffer_free; | 114 | uint32_t buffer_free; |
| 114 | int pid; | 115 | int pid; |
| 116 | size_t pages_high; | ||
| 115 | }; | 117 | }; |
| 116 | 118 | ||
| 117 | #ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST | 119 | #ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST |
| @@ -128,7 +130,7 @@ extern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, | |||
| 128 | size_t extra_buffers_size, | 130 | size_t extra_buffers_size, |
| 129 | int is_async); | 131 | int is_async); |
| 130 | extern void binder_alloc_init(struct binder_alloc *alloc); | 132 | extern void binder_alloc_init(struct binder_alloc *alloc); |
| 131 | void binder_alloc_shrinker_init(void); | 133 | extern int binder_alloc_shrinker_init(void); |
| 132 | extern void binder_alloc_vma_close(struct binder_alloc *alloc); | 134 | extern void binder_alloc_vma_close(struct binder_alloc *alloc); |
| 133 | extern struct binder_buffer * | 135 | extern struct binder_buffer * |
| 134 | binder_alloc_prepare_to_free(struct binder_alloc *alloc, | 136 | binder_alloc_prepare_to_free(struct binder_alloc *alloc, |
